From 2a20a5bd55b698bafcd622b494a0c5c486a0cc15 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 22 Feb 2017 18:00:36 -0500 Subject: [PATCH 01/14] balls move --- src/marching_cubes.js | 170 ++++++++++++++++++++++++++++++++---------- src/metaball.js | 13 +++- 2 files changed, 143 insertions(+), 40 deletions(-) diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 505eb24..de6a326 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -4,11 +4,26 @@ import Metaball from './metaball.js'; import InspectPoint from './inspect_point.js' import LUT from './marching_cube_LUT.js'; var VISUAL_DEBUG = true; +var episolon = 0.1; +var balls = []; const LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0xeeeeee }); const LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 }); const WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } ); +// This function samples a point from the metaball's density function +// Implement a function that returns the value of the all metaballs influence to a given point. +// Please follow the resources given in the write-up for details. +function sample(point) { + // @TODO + var isovalue = 0.0; + for (var i = 0; i < balls.length; i ++) { + var r = balls[i].radius; + var d = point.distanceTo(balls[i].pos); + isovalue += r * r / (d * d); + } + return isovalue; +} export default class MarchingCubes { @@ -43,8 +58,8 @@ export default class MarchingCubes { this.scene = App.scene; this.voxels = []; - this.labels = []; - this.balls = []; + //this.labels = []; + this.balls = balls; this.showSpheres = true; this.showGrid = true; @@ -67,10 +82,10 @@ export default class MarchingCubes { // @note: ~~ is a fast substitute for Math.floor() return [ - i1 % this.res, - ~~ ((i1 % this.res2) / this.res), - ~~ (i1 / this.res2) - ]; + i1 % this.res, + ~~ ((i1 % this.res2) / this.res), + ~~ (i1 / this.res2) + ]; }; // Convert from 3D indices to 1 1D @@ -110,8 +125,6 @@ export default class MarchingCubes { setupMetaballs() { - this.balls = []; - var x, y, z, vx, vy, vz, radius, pos, vel; var matLambertWhite = LAMBERT_WHITE; var maxRadiusTRippled = this.maxRadius * 3; @@ -130,23 +143,16 @@ export default class MarchingCubes { vel = new THREE.Vector3(vx, vy, vz); radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius; - + var ball = new Metaball(pos, radius, vel, this.gridWidth, VISUAL_DEBUG); - this.balls.push(ball); + balls.push(ball); + if (VISUAL_DEBUG) { this.scene.add(ball.mesh); } } - } - - // This function samples a point from the metaball's density function - // Implement a function that returns the value of the all metaballs influence to a given point. - // Please follow the resources given in the write-up for details. - sample(point) { - // @TODO - var isovalue = 1.1; - return isovalue; + this.balls = balls; } update() { @@ -156,18 +162,22 @@ export default class MarchingCubes { } // This should move the metaballs - this.balls.forEach(function(ball) { + balls.forEach(function(ball) { ball.update(); }); + this.balls = balls; - for (var c = 0; c < this.res3; c++) { + for (var c = 0; c < this.res3; c++) { // every voxel - // Sampling the center point - this.voxels[c].center.isovalue = this.sample(this.voxels[c].center.pos); + // Sampling the center and vertex points + this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos); + for (var i = 0; i < 8; i ++) { + this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos); + } // Visualizing grid if (VISUAL_DEBUG && this.showGrid) { - + // Toggle voxels on or off if (this.voxels[c].center.isovalue > this.isolevel) { this.voxels[c].show(); @@ -207,10 +217,25 @@ export default class MarchingCubes { makeMesh() { // @TODO + this.geo = new THREE.Geometry(); + this.mesh = new THREE.Mesh(this.geo, LAMBERT_WHITE); } updateMesh() { // @TODO + var vertices = []; + var normals = []; + for (var i = 0; i < this.res3; i ++) { + var vANDn = this.voxels[i].polygonize(this.isolevel); + for (var j = 0; j < vANDn.vertPositions.length; j ++) { + vertices.push(vANDn.vertPositions[j]); + normals.push(vANDn.vertNormals[j]); + } + } + this.geo.vertices = vertices; + this.geo.normals = normals; + this.geo.verticesNeedUpdate = true; + this.geo.normalsNeedUpdate = true; } }; @@ -225,6 +250,7 @@ class Voxel { init(position, gridCellWidth) { this.pos = position; this.gridCellWidth = gridCellWidth; + this.corners = []; if (VISUAL_DEBUG) { this.makeMesh(); @@ -238,17 +264,17 @@ class Voxel { var positions = new Float32Array([ // Front face - halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, - halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, + halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, + halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, // Back face -halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, - halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, - halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, - ]); + halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, + halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, + ]); var indices = new Uint16Array([ 0, 1, 2, 3, @@ -257,7 +283,7 @@ class Voxel { 4, 3, 3, 0, 1, 6, 6, 5, 5, 2, 2, 1 - ]); + ]); // Buffer geometry var geo = new THREE.BufferGeometry(); @@ -275,14 +301,22 @@ class Voxel { } makeInspectPoints() { - var halfGridCellWidth = this.gridCellWidth / 2.0; + var h = this.gridCellWidth / 2.0; var x = this.pos.x; var y = this.pos.y; var z = this.pos.z; var red = 0xff0000; // Center dot - this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG); + this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG); + this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y-h, z-h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y-h, z-h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y-h, z+h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y-h, z+h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y+h, z-h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y+h, z-h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y+h, z+h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y+h, z+h), 0, VISUAL_DEBUG)); } show() { @@ -308,22 +342,80 @@ class Voxel { } } - vertexInterpolation(isolevel, posA, posB) { + vertexLerp(isolevel, posA, posB) { + var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue); + var lerpPos = new THREE.Vector3(); + return lerpPos.lerpVectors(posA.pos, posB.pos, t); + } + + // returns an array of points on the cube edges + // null if no point exists for an edge + edgePoints(edges, x) { + var points = [null, null, null, null, null, null, null, null, null, null, null, null]; + if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]); + if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]); + if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]); + if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]); + if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]); + if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]); + if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]); + if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]); + if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]); + if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]); + if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]); + if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]); + return points; + } - // @TODO - var lerpPos; - return lerpPos; + getNormal(point) { + var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z); + var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z); + var x = sample(x1) - sample(x0); + var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z); + var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z); + var y = sample(y1) - sample(y0); + var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon); + var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon); + var z = sample(z1) - sample(z0); + var n = new THREE.Vector3(x,y,z); + return n.normalize(); } polygonize(isolevel) { - // @TODO var vertexList = []; var normalList = []; + // get corner vertices that are inside metaballs + var corner = 1; + var allVert = 0; + for (var i = 0; i < 8; i ++) { + if (this.corners[i].isovalue > isolevel) { + allVert = allVert | corner; + } + corner = corner << 1; + } + + if (allVert == 0) { + // get intersected edges + var edges = LUT.EDGE_TABLE[allVert]; + + // get 12 points + var points = this.edgePoints(edges); + + for (var j = 0; j < 16; j ++) { + var tri = LUT.TRI_TABLE[edges + j]; + if (tri < 0) break; + var vertex = points[tri]; + vertexList.push(vertex); + normalList.push(this.getNormal(vertex)); + } + } + + return { - vertPositions: vertPositions, - vertNormals: vertNormals + vertPositions: vertexList, + vertNormals: normalList }; }; } \ No newline at end of file diff --git a/src/metaball.js b/src/metaball.js index 6a057bc..5831553 100644 --- a/src/metaball.js +++ b/src/metaball.js @@ -41,6 +41,17 @@ export default class Metaball { }; update() { - // @TODO + var date = new Date(); + var velocity = new THREE.Vector3(); + velocity.copy(this.vel); + this.pos.add(velocity); + + var x = (this.pos.x + this.radius) > this.gridWidth || (this.pos.x + this.radius) < 0; + var y = (this.pos.y + this.radius) > this.gridWidth || (this.pos.y + this.radius) < 0; + var z = (this.pos.z + this.radius) > this.gridWidth || (this.pos.z + this.radius) < 0; + if (x || y || z) { + this.vel.multiplyScalar(-1); + } + this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); } } \ No newline at end of file From f256dda7ecb52e7e4902d8fe07c6d382732822d6 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Wed, 22 Feb 2017 18:44:58 -0500 Subject: [PATCH 02/14] no mesh:( --- src/marching_cubes.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/marching_cubes.js b/src/marching_cubes.js index de6a326..586473f 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -147,7 +147,6 @@ export default class MarchingCubes { var ball = new Metaball(pos, radius, vel, this.gridWidth, VISUAL_DEBUG); balls.push(ball); - if (VISUAL_DEBUG) { this.scene.add(ball.mesh); } @@ -219,6 +218,8 @@ export default class MarchingCubes { // @TODO this.geo = new THREE.Geometry(); this.mesh = new THREE.Mesh(this.geo, LAMBERT_WHITE); + this.mesh.geometry.dynamic = true; + this.scene.add(this.mesh); } updateMesh() { @@ -391,20 +392,20 @@ class Voxel { var allVert = 0; for (var i = 0; i < 8; i ++) { if (this.corners[i].isovalue > isolevel) { - allVert = allVert | corner; + allVert |= corner; } corner = corner << 1; } - if (allVert == 0) { + if (allVert != 0) { // get intersected edges var edges = LUT.EDGE_TABLE[allVert]; // get 12 points - var points = this.edgePoints(edges); + var points = this.edgePoints(edges, isolevel); for (var j = 0; j < 16; j ++) { - var tri = LUT.TRI_TABLE[edges + j]; + var tri = LUT.TRI_TABLE[allVert*16 + j]; if (tri < 0) break; var vertex = points[tri]; vertexList.push(vertex); From cd5494d9b460f1f9f5e12c5928e8209216d2626e Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Thu, 23 Feb 2017 18:01:28 -0500 Subject: [PATCH 03/14] metaballll$$$ --- src/main.js | 14 +++---- src/marching_cubes.js | 85 ++++++++++++++++++++++++------------------- src/metaball.js | 8 ++-- 3 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/main.js b/src/main.js index 29f2f30..e32bb01 100644 --- a/src/main.js +++ b/src/main.js @@ -10,9 +10,9 @@ import Framework from './framework' import LUT from './marching_cube_LUT.js' import MarchingCubes from './marching_cubes.js' -const DEFAULT_VISUAL_DEBUG = true; +const DEFAULT_VISUAL_DEBUG = false; const DEFAULT_ISO_LEVEL = 1.0; -const DEFAULT_GRID_RES = 4; +const DEFAULT_GRID_RES = 16; const DEFAULT_GRID_WIDTH = 10; const DEFAULT_NUM_METABALLS = 10; const DEFAULT_MIN_RADIUS = 0.5; @@ -20,11 +20,11 @@ const DEFAULT_MAX_RADIUS = 1; const DEFAULT_MAX_SPEED = 0.01; var App = { - // + // marchingCubes: undefined, config: { - // Global control of all visual debugging. - // This can be set to false to disallow any memory allocation of visual debugging components. + // Global control of all visual debugging. + // This can be set to false to disallow any memory allocation of visual debugging components. // **Note**: If your application experiences performance drop, disable this flag. visualDebug: DEFAULT_VISUAL_DEBUG, @@ -113,7 +113,7 @@ function setupScene(scene) { function setupGUI(gui) { // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage - + // --- CONFIG --- gui.add(App, 'isPaused').onChange(function(value) { App.isPaused = value; @@ -153,7 +153,7 @@ function setupGUI(gui) { } } }); - debugFolder.open(); + debugFolder.open(); } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 586473f..02c5e77 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -27,12 +27,12 @@ function sample(point) { export default class MarchingCubes { - constructor(App) { + constructor(App) { this.init(App); } init(App) { - this.isPaused = false; + this.isPaused = false; VISUAL_DEBUG = App.config.visualDebug; // Initializing member variables. @@ -120,7 +120,7 @@ export default class MarchingCubes { this.scene.add(voxel.wireframe); this.scene.add(voxel.mesh); } - } + } } setupMetaballs() { @@ -132,21 +132,21 @@ export default class MarchingCubes { // Randomly generate metaballs with different sizes and velocities for (var i = 0; i < this.numMetaballs; i++) { - x = this.gridWidth / 2; - y = this.gridWidth / 2; - z = this.gridWidth / 2; + x = this.gridWidth / 2; + y = this.gridWidth / 2; + z = this.gridWidth / 2; pos = new THREE.Vector3(x, y, z); - + vx = (Math.random() * 2 - 1) * this.maxSpeed; vy = (Math.random() * 2 - 1) * this.maxSpeed; vz = (Math.random() * 2 - 1) * this.maxSpeed; vel = new THREE.Vector3(vx, vy, vz); - + radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius; var ball = new Metaball(pos, radius, vel, this.gridWidth, VISUAL_DEBUG); balls.push(ball); - + if (VISUAL_DEBUG) { this.scene.add(ball.mesh); } @@ -216,8 +216,8 @@ export default class MarchingCubes { makeMesh() { // @TODO - this.geo = new THREE.Geometry(); - this.mesh = new THREE.Mesh(this.geo, LAMBERT_WHITE); + var geo = new THREE.Geometry(); + this.mesh = new THREE.Mesh(geo, LAMBERT_WHITE); this.mesh.geometry.dynamic = true; this.scene.add(this.mesh); } @@ -226,18 +226,26 @@ export default class MarchingCubes { // @TODO var vertices = []; var normals = []; + var faces = []; + var count = 0; for (var i = 0; i < this.res3; i ++) { var vANDn = this.voxels[i].polygonize(this.isolevel); - for (var j = 0; j < vANDn.vertPositions.length; j ++) { - vertices.push(vANDn.vertPositions[j]); - normals.push(vANDn.vertNormals[j]); + for (var j = 0; j < vANDn.vertPositions.length/3; j ++) { + for (var k = 0; k < 3; k ++) { + vertices.push(vANDn.vertPositions[k*j]); + normals.push(vANDn.vertNormals[k*j]); + count++; + } + faces.push(new THREE.Face3(count - 3, count - 2, count - 1)); } } - this.geo.vertices = vertices; - this.geo.normals = normals; - this.geo.verticesNeedUpdate = true; - this.geo.normalsNeedUpdate = true; - } + this.mesh.geometry.vertices = vertices; + this.mesh.geometry.normals = normals; + this.mesh.geometry.faces = faces; + this.mesh.geometry.verticesNeedUpdate = true; + this.mesh.geometry.normalsNeedUpdate = true; + this.mesh.geometry.elementsNeedUpdate = true; + } }; // ------------------------------------------- // @@ -256,8 +264,8 @@ class Voxel { if (VISUAL_DEBUG) { this.makeMesh(); } - - this.makeInspectPoints(); + + this.makeInspectPoints(); } makeMesh() { @@ -386,6 +394,7 @@ class Voxel { var vertexList = []; var normalList = []; + var faceList = []; // get corner vertices that are inside metaballs var corner = 1; @@ -402,21 +411,21 @@ class Voxel { var edges = LUT.EDGE_TABLE[allVert]; // get 12 points - var points = this.edgePoints(edges, isolevel); - - for (var j = 0; j < 16; j ++) { - var tri = LUT.TRI_TABLE[allVert*16 + j]; - if (tri < 0) break; - var vertex = points[tri]; - vertexList.push(vertex); - normalList.push(this.getNormal(vertex)); + var points = this.edgePoints(edges, isolevel); + + for (var j = 0; j < 16; j ++) { + var tri = LUT.TRI_TABLE[allVert*16 + j]; + if (tri < 0) break; + var vertex = points[tri]; + vertexList.push(vertex); + normalList.push(this.getNormal(vertex)); + } + } + + + return { + vertPositions: vertexList, + vertNormals: normalList + }; + }; } - } - - - return { - vertPositions: vertexList, - vertNormals: normalList - }; - }; -} \ No newline at end of file diff --git a/src/metaball.js b/src/metaball.js index 5831553..6b0a9ee 100644 --- a/src/metaball.js +++ b/src/metaball.js @@ -16,8 +16,8 @@ export default class Metaball { this.radius = radius; this.radius2 = radius * radius; this.mesh = null; - - if (visualDebug) { + this.debug = visualDebug; + if (visualDebug) { this.makeMesh(); } } @@ -52,6 +52,6 @@ export default class Metaball { if (x || y || z) { this.vel.multiplyScalar(-1); } - this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); + if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); } -} \ No newline at end of file +} From 5011058cf9c4a7d7b5312e37386eb0e7bb5c3c56 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Thu, 23 Feb 2017 20:26:15 -0500 Subject: [PATCH 04/14] lit sphere shading --- src/main.js | 4 +- src/marching_cubes.js | 98 ++++++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 31 deletions(-) diff --git a/src/main.js b/src/main.js index e32bb01..845f7b9 100644 --- a/src/main.js +++ b/src/main.js @@ -12,7 +12,7 @@ import MarchingCubes from './marching_cubes.js' const DEFAULT_VISUAL_DEBUG = false; const DEFAULT_ISO_LEVEL = 1.0; -const DEFAULT_GRID_RES = 16; +const DEFAULT_GRID_RES = 30; const DEFAULT_GRID_WIDTH = 10; const DEFAULT_NUM_METABALLS = 10; const DEFAULT_MIN_RADIUS = 0.5; @@ -72,7 +72,7 @@ function onLoad(framework) { App.renderer = renderer; renderer.setClearColor( 0xbfd1e5 ); - scene.add(new THREE.AxisHelper(20)); + //scene.add(new THREE.AxisHelper(20)); setupCamera(App.camera); setupLights(App.scene); diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 02c5e77..7de73be 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -1,4 +1,5 @@ const THREE = require('three'); +import {fireTexture} from './shaders/textures' import Metaball from './metaball.js'; import InspectPoint from './inspect_point.js' @@ -6,7 +7,39 @@ import LUT from './marching_cube_LUT.js'; var VISUAL_DEBUG = true; var episolon = 0.1; var balls = []; +var fire; +var options = { + lightColor: '#ffffff', + lightIntensity: 1, + ambient: '#111111', + texture: null +} + +var mat = { + uniforms: { + texture: { + type: "t", + value: null + }, + u_ambient: { + type: 'v3', + value: new THREE.Color(options.ambient) + }, + u_lightCol: { + type: 'v3', + value: new THREE.Color(options.lightColor) + }, + u_lightIntensity: { + type: 'f', + value: options.lightIntensity + } + }, + vertexShader: require('./shaders/litsphere-vert.glsl'), + fragmentShader: require('./shaders/litsphere-frag.glsl') +}; + +const LIT_SPHERE = new THREE.ShaderMaterial(mat); const LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0xeeeeee }); const LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 }); const WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } ); @@ -64,6 +97,10 @@ export default class MarchingCubes { this.showSpheres = true; this.showGrid = true; + fireTexture.then(function(texture) { + mat.uniforms.texture.value = texture; + }); + if (App.config.material) { this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d}); } else { @@ -82,9 +119,9 @@ export default class MarchingCubes { // @note: ~~ is a fast substitute for Math.floor() return [ - i1 % this.res, - ~~ ((i1 % this.res2) / this.res), - ~~ (i1 / this.res2) + i1 % this.res, + ~~ ((i1 % this.res2) / this.res), + ~~ (i1 / this.res2) ]; }; @@ -103,7 +140,7 @@ export default class MarchingCubes { i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth, i3[1] * this.gridCellWidth + this.origin.y + this.halfCellWidth, i3[2] * this.gridCellWidth + this.origin.z + this.halfCellWidth - ); + ); }; setupCells() { @@ -217,7 +254,7 @@ export default class MarchingCubes { makeMesh() { // @TODO var geo = new THREE.Geometry(); - this.mesh = new THREE.Mesh(geo, LAMBERT_WHITE); + this.mesh = new THREE.Mesh(geo, LIT_SPHERE); this.mesh.geometry.dynamic = true; this.scene.add(this.mesh); } @@ -225,26 +262,29 @@ export default class MarchingCubes { updateMesh() { // @TODO var vertices = []; - var normals = []; var faces = []; var count = 0; for (var i = 0; i < this.res3; i ++) { + var vox_count = 0; var vANDn = this.voxels[i].polygonize(this.isolevel); for (var j = 0; j < vANDn.vertPositions.length/3; j ++) { + var normals = []; for (var k = 0; k < 3; k ++) { - vertices.push(vANDn.vertPositions[k*j]); - normals.push(vANDn.vertNormals[k*j]); + vertices.push(vANDn.vertPositions[vox_count]); + normals.push(vANDn.vertNormals[vox_count]); + vox_count++; count++; } - faces.push(new THREE.Face3(count - 3, count - 2, count - 1)); + faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals)); } } this.mesh.geometry.vertices = vertices; - this.mesh.geometry.normals = normals; + //this.mesh.geometry.normals = normals; this.mesh.geometry.faces = faces; this.mesh.geometry.verticesNeedUpdate = true; this.mesh.geometry.normalsNeedUpdate = true; this.mesh.geometry.elementsNeedUpdate = true; + this.mesh.geometry.computeFaceNormals(); } }; @@ -283,7 +323,7 @@ class Voxel { -halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, - ]); + ]); var indices = new Uint16Array([ 0, 1, 2, 3, @@ -292,7 +332,7 @@ class Voxel { 4, 3, 3, 0, 1, 6, 6, 5, 5, 2, 2, 1 - ]); + ]); // Buffer geometry var geo = new THREE.BufferGeometry(); @@ -411,21 +451,21 @@ class Voxel { var edges = LUT.EDGE_TABLE[allVert]; // get 12 points - var points = this.edgePoints(edges, isolevel); - - for (var j = 0; j < 16; j ++) { - var tri = LUT.TRI_TABLE[allVert*16 + j]; - if (tri < 0) break; - var vertex = points[tri]; - vertexList.push(vertex); - normalList.push(this.getNormal(vertex)); - } - } - - - return { - vertPositions: vertexList, - vertNormals: normalList - }; - }; + var points = this.edgePoints(edges, isolevel); + + for (var j = 0; j < 16; j ++) { + var tri = LUT.TRI_TABLE[allVert*16 + j]; + if (tri < 0) break; + var vertex = points[tri]; + vertexList.push(vertex); + normalList.push(this.getNormal(vertex)); } + } + + + return { + vertPositions: vertexList, + vertNormals: normalList + }; + }; +} From ed34491fa00c6e2f65a2be92b9fe8720e302933b Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Sat, 25 Feb 2017 16:04:49 -0500 Subject: [PATCH 05/14] lava lamp --- package.json | 1 + src/framework.js | 2 +- src/main.js | 85 +++++++++++++++++++++++--- src/marching_cubes.js | 136 +++++++++++++++++++++--------------------- src/metaball.js | 41 ++++++++----- 5 files changed, 173 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index a33a0dd..b3b6e73 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "gl-matrix": "^2.3.2", "stats-js": "^1.0.0-alpha1", "three": "^0.82.1", + "three-obj-loader": "^1.0.2", "three-orbit-controls": "^82.1.0" }, "devDependencies": { diff --git a/src/framework.js b/src/framework.js index aebfa7e..9912747 100644 --- a/src/framework.js +++ b/src/framework.js @@ -26,7 +26,7 @@ function init(callback, update) { var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ); - var renderer = new THREE.WebGLRenderer( { antialias: true } ); + var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} ); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0x020202, 0); diff --git a/src/main.js b/src/main.js index 845f7b9..7970a53 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,8 @@ require('file-loader?name=[name].[ext]!../index.html'); // http://paulbourke.net/geometry/polygonise/ const THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much +const OBJLoader = require('three-obj-loader'); +OBJLoader(THREE) import Framework from './framework' import LUT from './marching_cube_LUT.js' @@ -13,11 +15,43 @@ import MarchingCubes from './marching_cubes.js' const DEFAULT_VISUAL_DEBUG = false; const DEFAULT_ISO_LEVEL = 1.0; const DEFAULT_GRID_RES = 30; -const DEFAULT_GRID_WIDTH = 10; +const DEFAULT_GRID_WIDTH = 6; +const DEFAULT_GRID_HEIGHT = 15; +const DEFAULT_GRID_DEPTH = 6; const DEFAULT_NUM_METABALLS = 10; const DEFAULT_MIN_RADIUS = 0.5; const DEFAULT_MAX_RADIUS = 1; -const DEFAULT_MAX_SPEED = 0.01; +const DEFAULT_MAX_SPEEDX = 0.005; +const DEFAULT_MAX_SPEEDY = 0.03; + +var options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'} + +// glass, emissive, iridescent +var g_mat = { + uniforms: { + u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)}, + u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)}, + u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)}, + u_lightIntensity: {type: 'f',value: options.lightIntensity} + }, + vertexShader: require('./shaders/glass-vert.glsl'), + fragmentShader: require('./shaders/glass-frag.glsl') +}; + +// metal +var m_mat = { + uniforms: { + u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)}, + u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)}, + u_lightIntensity: {type: 'f',value: options.lightIntensity} + }, + vertexShader: require('./shaders/metal-vert.glsl'), + fragmentShader: require('./shaders/metal-frag.glsl') +}; + +//const GLASS_MAT = new THREE.ShaderMaterial(g_mat); +const GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3}); +const METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff}); var App = { // @@ -37,9 +71,15 @@ var App = { // Total width of grid gridWidth: DEFAULT_GRID_WIDTH, + gridHeight: DEFAULT_GRID_HEIGHT, + + gridDepth: DEFAULT_GRID_DEPTH, + // Width of each voxel - // Ideally, we want the voxel to be small (higher resolution) + // Ideally, we want the voxel to be small (higher resolution) gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES, + gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES, + gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES, // Number of metaballs numMetaballs: DEFAULT_NUM_METABALLS, @@ -51,7 +91,9 @@ var App = { maxRadius: DEFAULT_MAX_RADIUS, // Maximum speed of a metaball - maxSpeed: DEFAULT_MAX_SPEED + maxSpeedX: DEFAULT_MAX_SPEEDX, + maxSpeedY: DEFAULT_MAX_SPEEDY, + maxSpeedZ: DEFAULT_MAX_SPEEDX, }, // Scene's framework objects @@ -60,7 +102,8 @@ var App = { renderer: undefined, // Play/pause control for the simulation - isPaused: false + isPaused: false, + color: 0xffffff }; // called after the scene loads @@ -71,8 +114,25 @@ function onLoad(framework) { App.camera = camera; App.renderer = renderer; - renderer.setClearColor( 0xbfd1e5 ); - //scene.add(new THREE.AxisHelper(20)); + renderer.setClearColor( 0x111111 ); + scene.add(new THREE.AxisHelper(20)); + + var objLoader = new THREE.OBJLoader(); + var obj = objLoader.load('glass.obj', function(obj) { + var glassGeo = obj.children[0].geometry; + var glass = new THREE.Mesh(glassGeo, GLASS_MAT); + glass.translateX(-1.5); + glass.translateZ(-1.5); + App.scene.add(glass); + }); + + var obj = objLoader.load('lamp.obj', function(obj) { + var lampGeo = obj.children[0].geometry; + var lamp = new THREE.Mesh(lampGeo, METAL_MAT); + lamp.translateX(-1.5); + lamp.translateZ(-1.5); + App.scene.add(lamp); + }); setupCamera(App.camera); setupLights(App.scene); @@ -90,7 +150,7 @@ function onUpdate(framework) { function setupCamera(camera) { // set camera position - camera.position.set(5, 5, 30); + camera.position.set(-5, 5, -30); camera.lookAt(new THREE.Vector3(0,0,0)); } @@ -115,6 +175,15 @@ function setupGUI(gui) { // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage // --- CONFIG --- + gui.addColor(App, 'color').onChange(function(value) { + App.isPaused = value; + if (value) { + App.marchingCubes.pause(); + } else { + App.marchingCubes.play(); + } + }); + gui.add(App, 'isPaused').onChange(function(value) { App.isPaused = value; if (value) { diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 7de73be..5f71394 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -1,5 +1,5 @@ const THREE = require('three'); -import {fireTexture} from './shaders/textures' +import {silverTexture} from './textures' import Metaball from './metaball.js'; import InspectPoint from './inspect_point.js' @@ -7,40 +7,23 @@ import LUT from './marching_cube_LUT.js'; var VISUAL_DEBUG = true; var episolon = 0.1; var balls = []; -var fire; -var options = { - lightColor: '#ffffff', - lightIntensity: 1, - ambient: '#111111', - texture: null -} +var options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null}; -var mat = { +// lava +var l_mat = { uniforms: { - texture: { - type: "t", - value: null - }, - u_ambient: { - type: 'v3', - value: new THREE.Color(options.ambient) - }, - u_lightCol: { - type: 'v3', - value: new THREE.Color(options.lightColor) - }, - u_lightIntensity: { - type: 'f', - value: options.lightIntensity - } + texture: {type: "t",value: null}, + u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)}, + u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)}, + u_lightIntensity: {type: 'f',value: options.lightIntensity} }, - vertexShader: require('./shaders/litsphere-vert.glsl'), - fragmentShader: require('./shaders/litsphere-frag.glsl') + vertexShader: require('./shaders/lava-vert.glsl'), + fragmentShader: require('./shaders/lava-frag.glsl') }; -const LIT_SPHERE = new THREE.ShaderMaterial(mat); -const LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0xeeeeee }); +const LAVA_MAT = new THREE.ShaderMaterial(l_mat); +const LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 }); const LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 }); const WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } ); @@ -48,12 +31,11 @@ const WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: // Implement a function that returns the value of the all metaballs influence to a given point. // Please follow the resources given in the write-up for details. function sample(point) { - // @TODO var isovalue = 0.0; for (var i = 0; i < balls.length; i ++) { var r = balls[i].radius; var d = point.distanceTo(balls[i].pos); - isovalue += r * r / (d * d); + isovalue += (r * r / (d * d)) * balls[i].neg; } return isovalue; } @@ -77,14 +59,22 @@ export default class MarchingCubes { this.maxRadius = App.config.maxRadius; this.gridCellWidth = App.config.gridCellWidth; + this.gridCellHeight = App.config.gridCellHeight; + this.gridCellDepth = App.config.gridCellDepth; this.halfCellWidth = App.config.gridCellWidth / 2.0; + this.halfCellHeight = App.config.gridCellHeight / 2.0; + this.halfCellDepth = App.config.gridCellDepth / 2.0; this.gridWidth = App.config.gridWidth; + this.gridHeight = App.config.gridHeight; + this.gridDepth = App.config.gridDepth; this.res = App.config.gridRes; this.res2 = App.config.gridRes * App.config.gridRes; this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes; - this.maxSpeed = App.config.maxSpeed; + this.maxSpeedX = App.config.maxSpeedX; + this.maxSpeedY = App.config.maxSpeedY; + this.maxSpeedZ = App.config.maxSpeedZ; this.numMetaballs = App.config.numMetaballs; this.camera = App.camera; @@ -97,8 +87,8 @@ export default class MarchingCubes { this.showSpheres = true; this.showGrid = true; - fireTexture.then(function(texture) { - mat.uniforms.texture.value = texture; + silverTexture.then(function(texture) { + l_mat.uniforms.texture.value = texture; }); if (App.config.material) { @@ -138,8 +128,8 @@ export default class MarchingCubes { return new THREE.Vector3( i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth, - i3[1] * this.gridCellWidth + this.origin.y + this.halfCellWidth, - i3[2] * this.gridCellWidth + this.origin.z + this.halfCellWidth + i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight, + i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth ); }; @@ -150,7 +140,7 @@ export default class MarchingCubes { for (var i = 0; i < this.res3; i++) { var i3 = this.i1toi3(i); var {x, y, z} = this.i3toPos(i3); - var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth); + var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth); this.voxels.push(voxel); if (VISUAL_DEBUG) { @@ -170,23 +160,24 @@ export default class MarchingCubes { // Randomly generate metaballs with different sizes and velocities for (var i = 0; i < this.numMetaballs; i++) { x = this.gridWidth / 2; - y = this.gridWidth / 2; - z = this.gridWidth / 2; - pos = new THREE.Vector3(x, y, z); + y = this.gridHeight / 2; + z = this.gridDepth / 2; + pos = new THREE.Vector3(3, 3, 3); - vx = (Math.random() * 2 - 1) * this.maxSpeed; - vy = (Math.random() * 2 - 1) * this.maxSpeed; - vz = (Math.random() * 2 - 1) * this.maxSpeed; + vx = (Math.random() * 2 - 1) * this.maxSpeedX; + vy = (Math.random() * 2 - 1) * this.maxSpeedY; + vz = (Math.random() * 2 - 1) * this.maxSpeedZ; vel = new THREE.Vector3(vx, vy, vz); radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius; - - var ball = new Metaball(pos, radius, vel, this.gridWidth, VISUAL_DEBUG); + var neg = 1; + if (Math.random()>0.75) neg = -1; + var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG); balls.push(ball); - if (VISUAL_DEBUG) { - this.scene.add(ball.mesh); - } + // if (VISUAL_DEBUG) { + // this.scene.add(ball.mesh); + // } } this.balls = balls; } @@ -254,7 +245,7 @@ export default class MarchingCubes { makeMesh() { // @TODO var geo = new THREE.Geometry(); - this.mesh = new THREE.Mesh(geo, LIT_SPHERE); + this.mesh = new THREE.Mesh(geo, LAVA_MAT); this.mesh.geometry.dynamic = true; this.scene.add(this.mesh); } @@ -285,6 +276,7 @@ export default class MarchingCubes { this.mesh.geometry.normalsNeedUpdate = true; this.mesh.geometry.elementsNeedUpdate = true; this.mesh.geometry.computeFaceNormals(); + //console.log(this.mesh); } }; @@ -292,13 +284,15 @@ export default class MarchingCubes { class Voxel { - constructor(position, gridCellWidth) { - this.init(position, gridCellWidth); + constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) { + this.init(position, gridCellWidth, gridCellHeight, gridCellDepth); } - init(position, gridCellWidth) { + init(position, gridCellWidth, gridCellHeight, gridCellDepth) { this.pos = position; this.gridCellWidth = gridCellWidth; + this.gridCellHeight = gridCellHeight; + this.gridCellDepth = gridCellDepth; this.corners = []; if (VISUAL_DEBUG) { @@ -310,19 +304,21 @@ class Voxel { makeMesh() { var halfGridCellWidth = this.gridCellWidth / 2.0; + var halfGridCellHeight = this.gridCellHeight / 2.0; + var halfGridCellDepth = this.gridCellDepth / 2.0; var positions = new Float32Array([ // Front face - halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, - halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, - -halfGridCellWidth, -halfGridCellWidth, halfGridCellWidth, - -halfGridCellWidth, halfGridCellWidth, halfGridCellWidth, + halfGridCellWidth, halfGridCellHeight, halfGridCellDepth, + halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth, + -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth, + -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth, // Back face - -halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, - -halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, - halfGridCellWidth, -halfGridCellWidth, -halfGridCellWidth, - halfGridCellWidth, halfGridCellWidth, -halfGridCellWidth, + -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth, + -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth, + halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth, + halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth, ]); var indices = new Uint16Array([ @@ -350,7 +346,9 @@ class Voxel { } makeInspectPoints() { - var h = this.gridCellWidth / 2.0; + var w = this.gridCellWidth / 2.0; + var h = this.gridCellHeight / 2.0; + var d = this.gridCellDepth / 2.0; var x = this.pos.x; var y = this.pos.y; var z = this.pos.z; @@ -358,14 +356,14 @@ class Voxel { // Center dot this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG); - this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y-h, z-h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y-h, z-h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y-h, z+h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y-h, z+h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y+h, z-h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y+h, z-h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x+h, y+h, z+h), 0, VISUAL_DEBUG)); - this.corners.push(new InspectPoint(new THREE.Vector3(x-h, y+h, z+h), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG)); + this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG)); } show() { diff --git a/src/metaball.js b/src/metaball.js index 6b0a9ee..b5b33d1 100644 --- a/src/metaball.js +++ b/src/metaball.js @@ -4,22 +4,24 @@ var SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32); var LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 }); export default class Metaball { - constructor(pos, radius, vel, gridWidth, visualDebug) { - this.init(pos, radius, vel, gridWidth, visualDebug); + constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) { + this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug); } - init(pos, radius, vel, gridWidth, visualDebug) { + init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) { this.gridWidth = gridWidth; + this.gridHeight = gridHeight; + this.gridDepth = gridDepth; this.pos = pos; this.vel = vel; - + this.neg = neg; this.radius = radius; this.radius2 = radius * radius; this.mesh = null; this.debug = visualDebug; - if (visualDebug) { - this.makeMesh(); - } + // if (visualDebug) { + // this.makeMesh(); + // } } makeMesh() { @@ -41,17 +43,28 @@ export default class Metaball { }; update() { + + var cir = new THREE.Vector2(this.pos.x, this.pos.z); + var disp = new THREE.Vector2(this.gridWidth/2, this.gridWidth/2).sub(cir); + var dist = cir.distanceTo(new THREE.Vector2(this.gridWidth/2, this.gridWidth/2)); + var x = (this.pos.x + 2* this.radius) > this.gridWidth || (this.pos.x + 2 *this.radius) < 0; + if (x) this.vel.x *= -1; + var y = (this.pos.y + 2* this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0; + if (y) this.vel.y *= -1; + var z = (this.pos.z + 2* this.radius) > this.gridDepth || (this.pos.z + 2* this.radius) < 0; + if (z) this.vel.z *= -1; + var date = new Date(); var velocity = new THREE.Vector3(); - velocity.copy(this.vel); + velocity.copy(this.vel).multiplyScalar(3); this.pos.add(velocity); - var x = (this.pos.x + this.radius) > this.gridWidth || (this.pos.x + this.radius) < 0; - var y = (this.pos.y + this.radius) > this.gridWidth || (this.pos.y + this.radius) < 0; - var z = (this.pos.z + this.radius) > this.gridWidth || (this.pos.z + this.radius) < 0; - if (x || y || z) { - this.vel.multiplyScalar(-1); - } + + + + // if (x || y || z) { + // this.vel.multiplyScalar(-1); + // } if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); } } From a23091824740cfc369c6b53b010be261d0b1113a Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Sat, 25 Feb 2017 17:46:30 -0500 Subject: [PATCH 06/14] colored lamp --- index.html | 7 ++++++- src/main.js | 44 ++++++++++++++++++++++++------------------- src/marching_cubes.js | 7 ++++--- src/metaball.js | 18 +++++++++--------- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/index.html b/index.html index 0006574..7c9b79a 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - Project 6: Implicit Surfaces + Lava Lamp +
+

Inspirational Quote Here! +

+
+ diff --git a/src/main.js b/src/main.js index 7970a53..0ed19b8 100644 --- a/src/main.js +++ b/src/main.js @@ -16,7 +16,7 @@ const DEFAULT_VISUAL_DEBUG = false; const DEFAULT_ISO_LEVEL = 1.0; const DEFAULT_GRID_RES = 30; const DEFAULT_GRID_WIDTH = 6; -const DEFAULT_GRID_HEIGHT = 15; +const DEFAULT_GRID_HEIGHT = 17; const DEFAULT_GRID_DEPTH = 6; const DEFAULT_NUM_METABALLS = 10; const DEFAULT_MIN_RADIUS = 0.5; @@ -24,7 +24,12 @@ const DEFAULT_MAX_RADIUS = 1; const DEFAULT_MAX_SPEEDX = 0.005; const DEFAULT_MAX_SPEEDY = 0.03; -var options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'} +var options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'}; +var loaded = false; +var red = new THREE.Color(1.0,0.0,0.0); +var green = new THREE.Color(0.0,1.0,0.0); +var glassGeo; +var lampGeo; // glass, emissive, iridescent var g_mat = { @@ -50,8 +55,8 @@ var m_mat = { }; //const GLASS_MAT = new THREE.ShaderMaterial(g_mat); -const GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3}); -const METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff}); +var GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3}); +var METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff}); var App = { // @@ -115,19 +120,20 @@ function onLoad(framework) { App.renderer = renderer; renderer.setClearColor( 0x111111 ); - scene.add(new THREE.AxisHelper(20)); + //scene.add(new THREE.AxisHelper(20)); var objLoader = new THREE.OBJLoader(); var obj = objLoader.load('glass.obj', function(obj) { - var glassGeo = obj.children[0].geometry; + glassGeo = obj.children[0].geometry; var glass = new THREE.Mesh(glassGeo, GLASS_MAT); glass.translateX(-1.5); glass.translateZ(-1.5); App.scene.add(glass); + loaded = true; }); var obj = objLoader.load('lamp.obj', function(obj) { - var lampGeo = obj.children[0].geometry; + lampGeo = obj.children[0].geometry; var lamp = new THREE.Mesh(lampGeo, METAL_MAT); lamp.translateX(-1.5); lamp.translateZ(-1.5); @@ -140,9 +146,20 @@ function onLoad(framework) { setupGUI(gui); } +function cosine(a,b,c,d,t) { + return a + b * Math.cos(2.0 * Math.PI * (c * t + d)); +} + // called on frame updates function onUpdate(framework) { - + if (loaded) { + var date = new Date(); + var sec = date.getSeconds(); + var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0); + var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0); + var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); + GLASS_MAT.emissive.set(new THREE.Color(r,g,b)); + } if (App.marchingCubes) { App.marchingCubes.update(); } @@ -169,21 +186,10 @@ function setupScene(scene) { App.marchingCubes = new MarchingCubes(App); } - function setupGUI(gui) { // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage - // --- CONFIG --- - gui.addColor(App, 'color').onChange(function(value) { - App.isPaused = value; - if (value) { - App.marchingCubes.pause(); - } else { - App.marchingCubes.play(); - } - }); - gui.add(App, 'isPaused').onChange(function(value) { App.isPaused = value; if (value) { diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 5f71394..93841f7 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -35,7 +35,8 @@ function sample(point) { for (var i = 0; i < balls.length; i ++) { var r = balls[i].radius; var d = point.distanceTo(balls[i].pos); - isovalue += (r * r / (d * d)) * balls[i].neg; + //isovalue += (r * r / (d * d)) * balls[i].neg; + isovalue += (r * r / (d * d)); } return isovalue; } @@ -164,9 +165,9 @@ export default class MarchingCubes { z = this.gridDepth / 2; pos = new THREE.Vector3(3, 3, 3); - vx = (Math.random() * 2 - 1) * this.maxSpeedX; + vx = 0 vy = (Math.random() * 2 - 1) * this.maxSpeedY; - vz = (Math.random() * 2 - 1) * this.maxSpeedZ; + vz = 0 vel = new THREE.Vector3(vx, vy, vz); radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius; diff --git a/src/metaball.js b/src/metaball.js index b5b33d1..fc70f10 100644 --- a/src/metaball.js +++ b/src/metaball.js @@ -44,16 +44,16 @@ export default class Metaball { update() { - var cir = new THREE.Vector2(this.pos.x, this.pos.z); - var disp = new THREE.Vector2(this.gridWidth/2, this.gridWidth/2).sub(cir); - var dist = cir.distanceTo(new THREE.Vector2(this.gridWidth/2, this.gridWidth/2)); - var x = (this.pos.x + 2* this.radius) > this.gridWidth || (this.pos.x + 2 *this.radius) < 0; - if (x) this.vel.x *= -1; - var y = (this.pos.y + 2* this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0; + // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z); + // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir); + // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2)); + // if ((dist + 2*this.radius) > this.gridWidth + // || (dist + 2*this.radius) > this.gridDepth) { + // this.vel.add(disp); + // } + var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0; if (y) this.vel.y *= -1; - var z = (this.pos.z + 2* this.radius) > this.gridDepth || (this.pos.z + 2* this.radius) < 0; - if (z) this.vel.z *= -1; - + var date = new Date(); var velocity = new THREE.Vector3(); velocity.copy(this.vel).multiplyScalar(3); From f81e9fd77e539719f3c4d400524b2afbb56bc35f Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Sat, 25 Feb 2017 19:26:34 -0500 Subject: [PATCH 07/14] quotes --- index.html | 26 +++++++++++++--- src/framework.js | 3 +- src/main.js | 80 +++++++++++++++++++++++++----------------------- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/index.html b/index.html index 7c9b79a..e68ca85 100644 --- a/index.html +++ b/index.html @@ -11,14 +11,32 @@ width: 100%; height: 100%; } + .color{ + position: absolute; + right: 0px; + } + .container { + position: fixed; + right: 50px; + top: 50px; + width: 300px; + } + h1 { + color: white; + } + h3 { + color: white; + } -
-

Inspirational Quote Here! -

+
+
+

+

+
- + diff --git a/src/framework.js b/src/framework.js index 9912747..37880d0 100644 --- a/src/framework.js +++ b/src/framework.js @@ -14,7 +14,8 @@ function init(callback, update) { stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); - var gui = new DAT.GUI(); + var gui = new DAT.GUI({autoPlace: false}); + var framework = { gui: gui, diff --git a/src/main.js b/src/main.js index 0ed19b8..039f69c 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,6 @@ require('file-loader?name=[name].[ext]!../index.html'); - +import {silverTexture} from './textures' +//import {quote} from './quote' // Credit: // http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/ // http://paulbourke.net/geometry/polygonise/ @@ -56,7 +57,7 @@ var m_mat = { //const GLASS_MAT = new THREE.ShaderMaterial(g_mat); var GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3}); -var METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff}); +var METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111}); var App = { // @@ -167,8 +168,8 @@ function onUpdate(framework) { function setupCamera(camera) { // set camera position - camera.position.set(-5, 5, -30); - camera.lookAt(new THREE.Vector3(0,0,0)); + camera.position.set(25, 10, 25); + camera.lookAt(new THREE.Vector3(8,0,-5)); } function setupLights(scene) { @@ -190,45 +191,46 @@ function setupGUI(gui) { // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage - gui.add(App, 'isPaused').onChange(function(value) { - App.isPaused = value; - if (value) { - App.marchingCubes.pause(); - } else { - App.marchingCubes.play(); - } - }); - gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) { - App.config.numMetaballs = value; - App.marchingCubes.init(App); - }); + // gui.add(App, 'isPaused').onChange(function(value) { + // App.isPaused = value; + // if (value) { + // App.marchingCubes.pause(); + // } else { + // App.marchingCubes.play(); + // } + // }); - // --- DEBUG --- + // gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) { + // App.config.numMetaballs = value; + // App.marchingCubes.init(App); + // }); - var debugFolder = gui.addFolder('Debug'); - debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) { - App.marchingCubes.showGrid = value; - if (value) { - App.marchingCubes.show(); - } else { - App.marchingCubes.hide(); - } - }); + // --- DEBUG --- - debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) { - App.marchingCubes.showSpheres = value; - if (value) { - for (var i = 0; i < App.config.numMetaballs; i++) { - App.marchingCubes.balls[i].show(); - } - } else { - for (var i = 0; i < App.config.numMetaballs; i++) { - App.marchingCubes.balls[i].hide(); - } - } - }); - debugFolder.open(); + // var debugFolder = gui.addFolder('Debug'); + // debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) { + // App.marchingCubes.showGrid = value; + // if (value) { + // App.marchingCubes.show(); + // } else { + // App.marchingCubes.hide(); + // } + // }); + + // debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) { + // App.marchingCubes.showSpheres = value; + // if (value) { + // for (var i = 0; i < App.config.numMetaballs; i++) { + // App.marchingCubes.balls[i].show(); + // } + // } else { + // for (var i = 0; i < App.config.numMetaballs; i++) { + // App.marchingCubes.balls[i].hide(); + // } + // } + // }); + // debugFolder.open(); } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate From e2fb47edd41a2fb70ec302c788e5d956e820d70a Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Sat, 25 Feb 2017 20:25:09 -0500 Subject: [PATCH 08/14] new files --- .../Microsoft/Windows/IETldCache/index.dat | Bin 0 -> 16384 bytes build/assets/silver-3da470.bmp | Bin 0 -> 167142 bytes build/bundle.js | 49284 ++++++++++++++++ build/bundle.js.map | 1 + build/index.html | 42 + glass.mtl | 6 + glass.obj | 4423 ++ lamp.mtl | 6 + lamp.obj | 1211 + my-new-chrome-extension/.babelrc | 3 + my-new-chrome-extension/.bowerrc | 3 + my-new-chrome-extension/.editorconfig | 24 + my-new-chrome-extension/.gitattributes | 1 + my-new-chrome-extension/.gitignore | 10 + my-new-chrome-extension/.yo-rc.json | 6 + .../app/_locales/en/messages.json | 10 + .../app/images/icon-128.png | Bin 0 -> 5356 bytes .../app/images/icon-16.png | Bin 0 -> 758 bytes my-new-chrome-extension/app/manifest.json | 18 + .../app/scripts.babel/background.js | 7 + .../app/scripts.babel/chromereload.js | 23 + my-new-chrome-extension/bower.json | 7 + my-new-chrome-extension/gulpfile.babel.js | 135 + my-new-chrome-extension/package.json | 47 + my-new-chrome-extension/test/index.html | 29 + my-new-chrome-extension/test/spec/test.js | 11 + quote.js | 45 + src/assets/caspern.bmp | Bin 0 -> 270054 bytes src/assets/fire.bmp | Bin 0 -> 786486 bytes src/assets/green.bmp | Bin 0 -> 786486 bytes src/assets/silver.bmp | Bin 0 -> 167142 bytes src/assets/silverblue.bmp | Bin 0 -> 177930 bytes src/assets/smilelaugh.bmp | Bin 0 -> 1618398 bytes src/quote.js | 45 + src/shaders/glass-frag.glsl | 19 + src/shaders/glass-vert.glsl | 11 + src/shaders/lava-frag.glsl | 19 + src/shaders/lava-vert.glsl | 10 + src/shaders/metal-frag.glsl | 12 + src/shaders/metal-vert.glsl | 9 + src/textures.js | 10 + 41 files changed, 55487 insertions(+) create mode 100644 %APPDATA%/Microsoft/Windows/IETldCache/index.dat create mode 100644 build/assets/silver-3da470.bmp create mode 100644 build/bundle.js create mode 100644 build/bundle.js.map create mode 100644 build/index.html create mode 100644 glass.mtl create mode 100644 glass.obj create mode 100644 lamp.mtl create mode 100644 lamp.obj create mode 100644 my-new-chrome-extension/.babelrc create mode 100644 my-new-chrome-extension/.bowerrc create mode 100644 my-new-chrome-extension/.editorconfig create mode 100644 my-new-chrome-extension/.gitattributes create mode 100644 my-new-chrome-extension/.gitignore create mode 100644 my-new-chrome-extension/.yo-rc.json create mode 100644 my-new-chrome-extension/app/_locales/en/messages.json create mode 100644 my-new-chrome-extension/app/images/icon-128.png create mode 100644 my-new-chrome-extension/app/images/icon-16.png create mode 100644 my-new-chrome-extension/app/manifest.json create mode 100644 my-new-chrome-extension/app/scripts.babel/background.js create mode 100644 my-new-chrome-extension/app/scripts.babel/chromereload.js create mode 100644 my-new-chrome-extension/bower.json create mode 100644 my-new-chrome-extension/gulpfile.babel.js create mode 100644 my-new-chrome-extension/package.json create mode 100644 my-new-chrome-extension/test/index.html create mode 100644 my-new-chrome-extension/test/spec/test.js create mode 100644 quote.js create mode 100644 src/assets/caspern.bmp create mode 100644 src/assets/fire.bmp create mode 100644 src/assets/green.bmp create mode 100644 src/assets/silver.bmp create mode 100644 src/assets/silverblue.bmp create mode 100644 src/assets/smilelaugh.bmp create mode 100644 src/quote.js create mode 100644 src/shaders/glass-frag.glsl create mode 100644 src/shaders/glass-vert.glsl create mode 100644 src/shaders/lava-frag.glsl create mode 100644 src/shaders/lava-vert.glsl create mode 100644 src/shaders/metal-frag.glsl create mode 100644 src/shaders/metal-vert.glsl create mode 100644 src/textures.js diff --git a/%APPDATA%/Microsoft/Windows/IETldCache/index.dat b/%APPDATA%/Microsoft/Windows/IETldCache/index.dat new file mode 100644 index 0000000000000000000000000000000000000000..2eebd2c1b5efc891e14c56132e5c5f52d416aa52 GIT binary patch literal 16384 zcmeIuAqs#n06@_lWhXEQc41&!)Gjhm7>3~iJh~THv%VjHe5qdLe&X6{+K;ouoR_$j z7N=nhVGf<%&a(&*AV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs i0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&KLQ`#90^GP literal 0 HcmV?d00001 diff --git a/build/assets/silver-3da470.bmp b/build/assets/silver-3da470.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5d91b5fa965bcf0f943b591be20522064cdcc2e8 GIT binary patch literal 167142 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�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 0 ) ? 1 : + x; + + }; + + } + + if ( Function.prototype.name === undefined ) { + + // Missing in IE9-11. + // 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*)\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 ) { + + 'use strict'; + + 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; + + if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) { + + return true; + + } + + return false; + + }, + + 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 = '82'; + var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; + var CullFaceNone = 0; + var CullFaceBack = 1; + var CullFaceFront = 2; + var CullFaceFrontBack = 3; + var FrontFaceDirectionCW = 0; + var FrontFaceDirectionCCW = 1; + var BasicShadowMap = 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 BlendingMode = { + NoBlending: NoBlending, + NormalBlending: NormalBlending, + AdditiveBlending: AdditiveBlending, + SubtractiveBlending: SubtractiveBlending, + MultiplyBlending: MultiplyBlending, + CustomBlending: CustomBlending + }; + 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 TextureMapping = { + UVMapping: UVMapping, + CubeReflectionMapping: CubeReflectionMapping, + CubeRefractionMapping: CubeRefractionMapping, + EquirectangularReflectionMapping: EquirectangularReflectionMapping, + EquirectangularRefractionMapping: EquirectangularRefractionMapping, + SphericalReflectionMapping: SphericalReflectionMapping, + CubeUVReflectionMapping: CubeUVReflectionMapping, + CubeUVRefractionMapping: CubeUVRefractionMapping + }; + var RepeatWrapping = 1000; + var ClampToEdgeWrapping = 1001; + var MirroredRepeatWrapping = 1002; + var TextureWrapping = { + RepeatWrapping: RepeatWrapping, + ClampToEdgeWrapping: ClampToEdgeWrapping, + MirroredRepeatWrapping: MirroredRepeatWrapping + }; + var NearestFilter = 1003; + var NearestMipMapNearestFilter = 1004; + var NearestMipMapLinearFilter = 1005; + var LinearFilter = 1006; + var LinearMipMapNearestFilter = 1007; + var LinearMipMapLinearFilter = 1008; + var TextureFilter = { + NearestFilter: NearestFilter, + NearestMipMapNearestFilter: NearestMipMapNearestFilter, + NearestMipMapLinearFilter: NearestMipMapLinearFilter, + LinearFilter: LinearFilter, + LinearMipMapNearestFilter: LinearMipMapNearestFilter, + LinearMipMapLinearFilter: LinearMipMapLinearFilter + }; + 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 RGBEFormat = RGBAFormat; + 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 LogLuvEncoding = 3003; + 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 to range + + 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 ); + + }, + + random16: function () { + + console.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' ); + return Math.random(); + + }, + + // Random integer from interval + + randInt: function ( low, high ) { + + return low + Math.floor( Math.random() * ( high - low + 1 ) ); + + }, + + // Random float from 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; + + } + + Vector2.prototype = { + + constructor: Vector2, + + isVector2: true, + + get width() { + + return this.x; + + }, + + set width( value ) { + + this.x = value; + + }, + + get height() { + + return this.y; + + }, + + set height( value ) { + + this.y = value; + + }, + + // + + 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 ) { + + if ( isFinite( scalar ) ) { + + this.x *= scalar; + this.y *= scalar; + + } else { + + this.x = 0; + this.y = 0; + + } + + 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, max; + + return function clampScalar( minVal, maxVal ) { + + if ( min === undefined ) { + + min = new Vector2(); + max = new Vector2(); + + } + + 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; + + }, + + fromAttribute: function ( attribute, index, offset ) { + + if ( offset === undefined ) offset = 0; + + index = index * attribute.itemSize + offset; + + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + + 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/ + */ + + function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + + Object.defineProperty( this, 'id', { value: TextureIdCount() } ); + + this.uuid = _Math.generateUUID(); + + this.name = ''; + this.sourceFile = ''; + + 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; + + Texture.prototype = { + + constructor: Texture, + + isTexture: true, + + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + + }, + + clone: function () { + + return new this.constructor().copy( this ); + + }, + + copy: function ( source ) { + + 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.4, + 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; + + } + + } + + }; + + Object.assign( Texture.prototype, EventDispatcher.prototype ); + + var count = 0; + function TextureIdCount() { return count++; } + + /** + * @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; + + } + + Vector4.prototype = { + + constructor: Vector4, + + 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 ) { + + if ( isFinite( scalar ) ) { + + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; + + } else { + + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + + } + + 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, max; + + return function clampScalar( minVal, maxVal ) { + + if ( min === undefined ) { + + min = new Vector4(); + max = new Vector4(); + + } + + 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; + + }, + + fromAttribute: function ( attribute, index, offset ) { + + if ( offset === undefined ) offset = 0; + + index = index * attribute.itemSize + offset; + + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; + this.w = attribute.array[ index + 3 ]; + + 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; + + } + + Quaternion.prototype = { + + constructor: Quaternion, + + get x () { + + return this._x; + + }, + + set x ( value ) { + + this._x = value; + this.onChangeCallback(); + + }, + + get y () { + + return this._y; + + }, + + set y ( value ) { + + this._y = value; + this.onChangeCallback(); + + }, + + get z () { + + return this._z; + + }, + + set z ( value ) { + + this._z = value; + this.onChangeCallback(); + + }, + + get w () { + + return this._w; + + }, + + set w ( value ) { + + this._w = value; + this.onChangeCallback(); + + }, + + 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.' ); + + } + + // http://www.mathworks.com/matlabcentral/fileexchange/ + // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ + // content/SpinCalc.m + + var c1 = Math.cos( euler._x / 2 ); + var c2 = Math.cos( euler._y / 2 ); + var c3 = Math.cos( euler._z / 2 ); + var s1 = Math.sin( euler._x / 2 ); + var s2 = Math.sin( euler._y / 2 ); + var s3 = Math.sin( euler._z / 2 ); + + var order = euler.order; + + 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 () { + + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + + // assumes direction vectors vFrom and vTo are normalized + + var v1, 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 () {} + + }; + + 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; + + } + + } ); + + /** + * @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; + + } + + Vector3.prototype = { + + constructor: Vector3, + + 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 ) { + + if ( isFinite( scalar ) ) { + + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + + } else { + + this.x = 0; + this.y = 0; + this.z = 0; + + } + + 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; + + 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.' ); + + } + + if ( quaternion === undefined ) quaternion = new Quaternion(); + + return this.applyQuaternion( quaternion.setFromEuler( euler ) ); + + }; + + }(), + + applyAxisAngle: function () { + + var quaternion; + + return function applyAxisAngle( axis, angle ) { + + if ( quaternion === undefined ) quaternion = new Quaternion(); + + 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 ) { + + // input: THREE.Matrix4 affine matrix + + 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 ]; + + return this; + + }, + + applyProjection: function ( m ) { + + // input: THREE.Matrix4 projection matrix + + var x = this.x, y = this.y, z = this.z; + var e = m.elements; + var d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide + + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d; + + return this; + + }, + + 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; + + return function project( camera ) { + + if ( matrix === undefined ) matrix = new Matrix4(); + + matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) ); + return this.applyProjection( matrix ); + + }; + + }(), + + unproject: function () { + + var matrix; + + return function unproject( camera ) { + + if ( matrix === undefined ) matrix = new Matrix4(); + + matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) ); + return this.applyProjection( 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, max; + + return function clampScalar( minVal, maxVal ) { + + if ( min === undefined ) { + + min = new Vector3(); + max = new Vector3(); + + } + + 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; + + }, + + 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; + + return function projectOnPlane( planeNormal ) { + + if ( v1 === undefined ) v1 = new Vector3(); + + 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; + + return function reflect( normal ) { + + if ( v1 === undefined ) v1 = new Vector3(); + + 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; + + }, + + 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 ) { + + if ( typeof m === 'number' ) { + + console.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' ); + var temp = m; + m = index; + index = temp; + + } + + 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; + + }, + + fromAttribute: function ( attribute, index, offset ) { + + if ( offset === undefined ) offset = 0; + + index = index * attribute.itemSize + offset; + + this.x = attribute.array[ index ]; + this.y = attribute.array[ index + 1 ]; + this.z = attribute.array[ index + 2 ]; + + 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 = new Float32Array( [ + + 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.' ); + + } + + } + + Matrix4.prototype = { + + constructor: Matrix4, + + 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 ) { + + this.elements.set( m.elements ); + + return this; + + }, + + copyPosition: function ( m ) { + + var te = this.elements; + var 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; + + return function extractRotation( m ) { + + if ( v1 === undefined ) v1 = new Vector3(); + + 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, y, z; + + return function lookAt( eye, target, up ) { + + if ( x === undefined ) { + + x = new Vector3(); + y = new Vector3(); + z = new Vector3(); + + } + + var te = this.elements; + + z.subVectors( eye, target ).normalize(); + + if ( z.lengthSq() === 0 ) { + + z.z = 1; + + } + + x.crossVectors( up, z ).normalize(); + + if ( x.lengthSq() === 0 ) { + + z.z += 0.0001; + x.crossVectors( up, z ).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; + + }, + + multiplyToArray: function ( a, b, r ) { + + var te = this.elements; + + this.multiplyMatrices( a, b ); + + r[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ]; + r[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ]; + r[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ]; + r[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ]; + + 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; + + }, + + applyToVector3Array: function () { + + var v1; + + return function applyToVector3Array( array, offset, length ) { + + if ( v1 === undefined ) v1 = new Vector3(); + if ( offset === undefined ) offset = 0; + if ( length === undefined ) length = array.length; + + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { + + v1.fromArray( array, j ); + v1.applyMatrix4( this ); + v1.toArray( array, j ); + + } + + return array; + + }; + + }(), + + applyToBuffer: function () { + + var v1; + + return function applyToBuffer( buffer, offset, length ) { + + if ( v1 === undefined ) v1 = new Vector3(); + if ( offset === undefined ) offset = 0; + if ( length === undefined ) length = buffer.length / buffer.itemSize; + + for ( var i = 0, j = offset; i < length; i ++, j ++ ) { + + v1.x = buffer.getX( j ); + v1.y = buffer.getY( j ); + v1.z = buffer.getZ( j ); + + v1.applyMatrix4( this ); + + buffer.setXYZ( j, v1.x, v1.y, v1.z ); + + } + + return buffer; + + }; + + }(), + + 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; + + }, + + flattenToArrayOffset: function ( array, offset ) { + + console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " + + "- just 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 ); + + }; + + }(), + + 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; + + }, + + compose: function ( position, quaternion, scale ) { + + this.makeRotationFromQuaternion( quaternion ); + this.scale( scale ); + this.setPosition( position ); + + return this; + + }, + + decompose: function () { + + var vector, matrix; + + return function decompose( position, quaternion, scale ) { + + if ( vector === undefined ) { + + vector = new Vector3(); + matrix = new Matrix4(); + + } + + 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.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy() + + 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; + + }; + + }(), + + makeFrustum: function ( left, right, bottom, top, near, far ) { + + 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; + + }, + + makePerspective: function ( fov, aspect, near, far ) { + + var ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 ); + var ymin = - ymax; + var xmin = ymin * aspect; + var xmax = ymax * aspect; + + return this.makeFrustum( xmin, xmax, ymin, ymax, near, far ); + + }, + + 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 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 = []; + + // 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 ) { + + gl.uniformMatrix3fv( this.addr, false, v.elements || v ); + + } + + function setValue4fm( gl, v ) { + + gl.uniformMatrix4fv( this.addr, false, v.elements || v ); + + } + + // 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.set = function( gl, object, name ) { + + var u = this.map[ name ]; + + if ( u !== undefined ) u.setValue( gl, object[ name ], 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; + + }; + + /** + * 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 = "bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\n\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t\t}\n\t\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}\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 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}\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 return value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n float maxComponent = max( max( value.r, value.g ), value.b );\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n M = ceil( M * 255.0 ) / 255.0;\n return vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float D = max( maxRange / maxRGB, 1.0 );\n D = min( floor( D ) / 255.0, 1.0 );\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n vec4 vResult;\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n vResult.w = fract(Le);\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n return 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 float Le = value.z * 255.0 + value.w;\n vec3 Xp_Y_XYZp;\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n return 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 envMapIntenstiy;\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_fragment = "#ifdef USE_FOG\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\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\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"; + + 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\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\n\t\t\tdirectLight.color = pointLight.color;\n\t\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\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_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\t#include \n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\t#include \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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\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_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}\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_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 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\t\t\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.r;\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 return normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n return 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 return ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n return linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n return ( 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 roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.r;\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 boneTextureWidth;\n\t\tuniform int boneTextureHeight;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureWidth ) );\n\t\t\tfloat y = floor( j / float( boneTextureWidth ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureWidth );\n\t\t\tfloat dy = 1.0 / float( boneTextureHeight );\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 return toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return 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 color *= toneMappingExposure;\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n color = max( vec3( 0.0 ), color - 0.004 );\n return 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 \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 \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n"; + + var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \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 \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var distanceRGBA_frag = "uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include \n#include \n#include \nvoid main () {\n\t#include \n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n"; + + var distanceRGBA_vert = "varying vec4 vWorldPosition;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition;\n}\n"; + + var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \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 \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n"; + + var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \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 \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n}\n"; + + var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight;\n\treflectedLight.directDiffuse = vec3( 0.0 );\n\treflectedLight.directSpecular = vec3( 0.0 );\n\treflectedLight.indirectDiffuse = diffuseColor.rgb;\n\treflectedLight.indirectSpecular = vec3( 0.0 );\n\t#include \n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \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 \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \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 \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \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 \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \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 \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \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\nuniform float envMapIntensity;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \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 \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n}\n"; + + var normal_frag = "uniform float opacity;\nvarying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\n\t#include \n}\n"; + + var normal_vert = "varying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\tvNormal = normalize( normalMatrix * normal );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + + var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \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 \n\t#include \n\t#include \n\t#include \n}\n"; + + var shadow_frag = "uniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n"; + + var shadow_vert = "#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \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_fragment: fog_fragment, + fog_pars_fragment: fog_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, + 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 mrdoob / http://mrdoob.com/ + */ + + 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 ); + + } + + Color.prototype = { + + constructor: Color, + + 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(); + + } + + }; + + 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 }; + + /** + * 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 } + + }, + + 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: {} + } } + + }, + + 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 ) } + + } + + }; + + /** + * @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.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.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 }, + 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: { + + 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 ); + + } + + Box2.prototype = { + + constructor: Box2, + + 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 ) { + + if ( point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y ) { + + return false; + + } + + return true; + + }, + + containsBox: function ( box ) { + + if ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) && + ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) { + + return true; + + } + + return false; + + }, + + 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 6 splitting planes to rule out intersections. + + if ( box.max.x < this.min.x || box.min.x > this.max.x || + box.max.y < this.min.y || box.min.y > this.max.y ) { + + return false; + + } + + return 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.setDepthWrite( 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.applyProjection( 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.setDepthWrite( 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 && 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 && 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.setDepthTest( material.depthTest ); + state.setDepthWrite( 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/ + */ + + function Material() { + + Object.defineProperty( this, 'id', { value: MaterialIdCount() } ); + + 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.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; + + } + + Material.prototype = { + + constructor: Material, + + isMaterial: true, + + get needsUpdate() { + + return this._needsUpdate; + + }, + + set needsUpdate( value ) { + + if ( value === true ) this.update(); + this._needsUpdate = value; + + }, + + 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.4, + 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.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.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; + + // 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.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; + + }, + + update: function () { + + this.dispatchEvent( { type: 'update' } ); + + }, + + dispose: function () { + + this.dispatchEvent( { type: 'dispose' } ); + + } + + }; + + Object.assign( Material.prototype, EventDispatcher.prototype ); + + var count$1 = 0; + function MaterialIdCount() { return count$1++; } + + /** + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * defines: { "label" : "value" }, + * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, + * + * fragmentShader: , + * vertexShader: , + * + * wireframe: , + * wireframeLinewidth: , + * + * lights: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ + + 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: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ + + 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 ); + + } + + Box3.prototype = { + + constructor: Box3, + + 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 ); + + }, + + 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 () { + + // 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 setFromObject( object ) { + + var scope = this; + + object.updateMatrixWorld( true ); + + this.makeEmpty(); + + object.traverse( function ( node ) { + + var geometry = node.geometry; + + if ( geometry !== undefined ) { + + if ( (geometry && geometry.isGeometry) ) { + + var vertices = geometry.vertices; + + for ( var i = 0, il = vertices.length; i < il; i ++ ) { + + v1.copy( vertices[ i ] ); + v1.applyMatrix4( node.matrixWorld ); + + scope.expandByPoint( v1 ); + + } + + } else if ( (geometry && geometry.isBufferGeometry) ) { + + var attribute = geometry.attributes.position; + + if ( attribute !== undefined ) { + + var array, offset, stride; + + if ( (attribute && attribute.isInterleavedBufferAttribute) ) { + + array = attribute.data.array; + offset = attribute.offset; + stride = attribute.data.stride; + + } else { + + array = attribute.array; + offset = 0; + stride = 3; + + } + + for ( var i = offset, il = array.length; i < il; i += stride ) { + + v1.fromArray( array, i ); + v1.applyMatrix4( node.matrixWorld ); + + scope.expandByPoint( v1 ); + + } + + } + + } + + } + + } ); + + 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 = 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; + + }, + + containsPoint: function ( point ) { + + if ( 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 ) { + + return false; + + } + + return true; + + }, + + containsBox: function ( box ) { + + if ( ( 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 ) ) { + + return true; + + } + + return false; + + }, + + 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. + + if ( 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 ) { + + return false; + + } + + return true; + + }, + + intersectsSphere: ( function () { + + var closestPoint; + + return function intersectsSphere( sphere ) { + + if ( closestPoint === undefined ) closestPoint = new Vector3(); + + // 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; + + } + + Sphere.prototype = { + + constructor: Sphere, + + 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 = new Float32Array( [ + + 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.' ); + + } + + } + + Matrix3.prototype = { + + constructor: Matrix3, + + 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 me = m.elements; + + this.set( + + me[ 0 ], me[ 3 ], me[ 6 ], + me[ 1 ], me[ 4 ], me[ 7 ], + me[ 2 ], me[ 5 ], 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; + + }, + + applyToVector3Array: function () { + + var v1; + + return function applyToVector3Array( array, offset, length ) { + + if ( v1 === undefined ) v1 = new Vector3(); + if ( offset === undefined ) offset = 0; + if ( length === undefined ) length = array.length; + + for ( var i = 0, j = offset; i < length; i += 3, j += 3 ) { + + v1.fromArray( array, j ); + v1.applyMatrix3( this ); + v1.toArray( array, j ); + + } + + return array; + + }; + + }(), + + applyToBuffer: function () { + + var v1; + + return function applyToBuffer( buffer, offset, length ) { + + if ( v1 === undefined ) v1 = new Vector3(); + if ( offset === undefined ) offset = 0; + if ( length === undefined ) length = buffer.length / buffer.itemSize; + + for ( var i = 0, j = offset; i < length; i ++, j ++ ) { + + v1.x = buffer.getX( j ); + v1.y = buffer.getY( j ); + v1.z = buffer.getZ( j ); + + v1.applyMatrix3( this ); + + buffer.setXYZ( j, v1.x, v1.y, v1.z ); + + } + + return buffer; + + }; + + }(), + + 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; + + }, + + flattenToArrayOffset: function ( array, offset ) { + + console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " + + "- just use .toArray instead." ); + + return this.toArray( array, offset ); + + }, + + 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; + + }, + + 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; + + } + + Plane.prototype = { + + constructor: Plane, + + 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() + + ]; + + } + + Frustum.prototype = { + + constructor: Frustum, + + 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(), + + _renderList = [], + + _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.clearColor( 1, 1, 1, 1 ); + _state.disable( _gl.BLEND ); + _state.setDepthTest( 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; + + _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; + + } else { + + faceCount = 1; + isPointLight = false; + + } + + if ( shadow.map === null ) { + + var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + + shadowCamera.updateProjectionMatrix(); + + } + + if ( (shadow && shadow.isSpotLightShadow) ) { + + shadow.update( light ); + + } + + var shadowMap = shadow.map; + var shadowMatrix = shadow.matrix; + + _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( _lightPositionWorld ); + + _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 ); + + var vpDimensions = cube2DViewPorts[ face ]; + _state.viewport( vpDimensions ); + + } else { + + _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 ); + + // update camera matrices and frustum + + _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + _frustum.setFromMatrix( _projScreenMatrix ); + + // set object matrices & frustum culling + + _renderList.length = 0; + + projectObject( scene, camera, shadowCamera ); + + // render shadow map + // render regular objects + + for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) { + + var object = _renderList[ j ]; + var geometry = _objects.update( object ); + var material = object.material; + + if ( (material && material.isMultiMaterial) ) { + + var groups = geometry.groups; + var materials = material.materials; + + for ( var k = 0, kl = groups.length; k < kl; k ++ ) { + + var group = groups[ k ]; + var groupMaterial = materials[ group.materialIndex ]; + + if ( groupMaterial.visible === true ) { + + var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); + + } + + } + + } else { + + var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); + + } + + } + + } + + } + + // Restore GL state. + var clearColor = _renderer.getClearColor(), + 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; + + } + + } + + 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 projectObject( object, camera, shadowCamera ) { + + if ( object.visible === false ) return; + + var visible = ( object.layers.mask & camera.layers.mask ) !== 0; + + if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { + + if ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) { + + var material = object.material; + + if ( material.visible === true ) { + + object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); + _renderList.push( object ); + + } + + } + + } + + var children = object.children; + + for ( var i = 0, l = children.length; i < l; i ++ ) { + + projectObject( children[ i ], camera, shadowCamera ); + + } + + } + + } + + /** + * @author bhouston / http://clara.io + */ + + function Ray( origin, direction ) { + + this.origin = ( origin !== undefined ) ? origin : new Vector3(); + this.direction = ( direction !== undefined ) ? direction : new Vector3(); + + } + + Ray.prototype = { + + constructor: Ray, + + 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'; + + Euler.prototype = { + + constructor: Euler, + + isEuler: true, + + get x () { + + return this._x; + + }, + + set x ( value ) { + + this._x = value; + this.onChangeCallback(); + + }, + + get y () { + + return this._y; + + }, + + set y ( value ) { + + this._y = value; + this.onChangeCallback(); + + }, + + get z () { + + return this._z; + + }, + + set z ( value ) { + + this._z = value; + this.onChangeCallback(); + + }, + + get order () { + + return this._order; + + }, + + set order ( value ) { + + this._order = value; + this.onChangeCallback(); + + }, + + 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; + + return function setFromQuaternion( q, order, update ) { + + if ( matrix === undefined ) matrix = new Matrix4(); + + 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; + + } + + Layers.prototype = { + + constructor: Layers, + + set: function ( channel ) { + + this.mask = 1 << channel; + + }, + + enable: function ( channel ) { + + this.mask |= 1 << channel; + + }, + + toggle: function ( channel ) { + + this.mask ^= 1 << channel; + + }, + + disable: function ( channel ) { + + this.mask &= ~ ( 1 << channel ); + + }, + + 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 + */ + + function Object3D() { + + Object.defineProperty( this, 'id', { value: Object3DIdCount() } ); + + 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 ) { + + 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 === true ) this.updateMatrix(); + + if ( this.matrixWorldNeedsUpdate === true || force === true ) { + + 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.4, + 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(); + + // + + if ( this.geometry !== undefined ) { + + if ( meta.geometries[ this.geometry.uuid ] === undefined ) { + + meta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta ); + + } + + object.geometry = this.geometry.uuid; + + } + + if ( this.material !== undefined ) { + + if ( meta.materials[ this.material.uuid ] === undefined ) { + + meta.materials[ this.material.uuid ] = this.material.toJSON( meta ); + + } + + object.material = this.material.uuid; + + } + + // + + 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.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; + + } + + } ); + + var count$2 = 0; + function Object3DIdCount() { return count$2++; } + + /** + * @author bhouston / http://clara.io + */ + + function Line3( start, end ) { + + this.start = ( start !== undefined ) ? start : new Vector3(); + this.end = ( end !== undefined ) ? end : new Vector3(); + + } + + Line3.prototype = { + + constructor: Line3, + + 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(); + + } + + 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 + Triangle.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 ); + + }; + + }(); + + Triangle.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 ); + + }; + + }(); + + Triangle.prototype = { + + constructor: Triangle, + + 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, edgeList, projectedPoint, closestPoint; + + return function closestPointToPoint( point, optionalTarget ) { + + if ( plane === undefined ) { + + plane = new Plane(); + edgeList = [ new Line3(), new Line3(), new Line3() ]; + projectedPoint = new Vector3(); + closestPoint = new Vector3(); + + } + + 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; + + } + + Face3.prototype = { + + constructor: Face3, + + 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: , + * opacity: , + * map: new THREE.Texture( ), + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * shading: THREE.SmoothShading, + * depthTest: , + * depthWrite: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: + * } + */ + + function MeshBasicMaterial( parameters ) { + + Material.call( this ); + + this.type = 'MeshBasicMaterial'; + + this.color = new Color( 0xffffff ); // emissive + + this.map = null; + + 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.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.version = 0; + + } + + BufferAttribute.prototype = { + + constructor: BufferAttribute, + + isBufferAttribute: true, + + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + + }, + + 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; + + }, + + clone: function () { + + return new this.constructor().copy( this ); + + } + + }; + + // + + function Int8Attribute( array, itemSize ) { + + return new BufferAttribute( new Int8Array( array ), itemSize ); + + } + + function Uint8Attribute( array, itemSize ) { + + return new BufferAttribute( new Uint8Array( array ), itemSize ); + + } + + function Uint8ClampedAttribute( array, itemSize ) { + + return new BufferAttribute( new Uint8ClampedArray( array ), itemSize ); + + } + + function Int16Attribute( array, itemSize ) { + + return new BufferAttribute( new Int16Array( array ), itemSize ); + + } + + function Uint16Attribute( array, itemSize ) { + + return new BufferAttribute( new Uint16Array( array ), itemSize ); + + } + + function Int32Attribute( array, itemSize ) { + + return new BufferAttribute( new Int32Array( array ), itemSize ); + + } + + function Uint32Attribute( array, itemSize ) { + + return new BufferAttribute( new Uint32Array( array ), itemSize ); + + } + + function Float32Attribute( array, itemSize ) { + + return new BufferAttribute( new Float32Array( array ), itemSize ); + + } + + function Float64Attribute( array, itemSize ) { + + return new BufferAttribute( new Float64Array( array ), itemSize ); + + } + + // Deprecated + + function DynamicBufferAttribute( array, itemSize ) { + + console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' ); + return new BufferAttribute( array, itemSize ).setDynamic( true ); + + } + + /** + * @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 + */ + + 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; + + return function rotateX( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationX( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + rotateY: function () { + + // rotate geometry around world y-axis + + var m1; + + return function rotateY( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationY( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + rotateZ: function () { + + // rotate geometry around world z-axis + + var m1; + + return function rotateZ( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationZ( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + translate: function () { + + // translate geometry + + var m1; + + return function translate( x, y, z ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeTranslation( x, y, z ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + scale: function () { + + // scale geometry + + var m1; + + return function scale( x, y, z ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeScale( x, y, z ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + lookAt: function () { + + var obj; + + return function lookAt( vector ) { + + if ( obj === undefined ) obj = new Object3D(); + + 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() ] ); + + } + + } + + if ( indices !== undefined ) { + + 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 ) { + + addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); + + } + + } + + } else { + + 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; + + } + + }, + + computeTangents: function () { + + console.warn( 'THREE.Geometry: .computeTangents() has been removed.' ); + + }, + + 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 ]; + + var dupIndex = - 1; + + // 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 ] ) { + + dupIndex = n; + 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.4, + 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 ) { + + this.vertices = []; + this.faces = []; + this.faceVertexUvs = [ [] ]; + this.colors = []; + + var vertices = source.vertices; + + for ( var i = 0, il = vertices.length; i < il; i ++ ) { + + this.vertices.push( vertices[ i ].clone() ); + + } + + var colors = source.colors; + + for ( var i = 0, il = colors.length; i < il; i ++ ) { + + this.colors.push( colors[ i ].clone() ); + + } + + var faces = source.faces; + + for ( var i = 0, il = faces.length; i < il; i ++ ) { + + this.faces.push( faces[ i ].clone() ); + + } + + for ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { + + var faceVertexUvs = source.faceVertexUvs[ i ]; + + if ( this.faceVertexUvs[ i ] === undefined ) { + + this.faceVertexUvs[ i ] = []; + + } + + for ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { + + var uvs = faceVertexUvs[ j ], uvsCopy = []; + + for ( var k = 0, kl = uvs.length; k < kl; k ++ ) { + + var uv = uvs[ k ]; + + uvsCopy.push( uv.clone() ); + + } + + this.faceVertexUvs[ i ].push( uvsCopy ); + + } + + } + + return this; + + }, + + dispose: function () { + + this.dispatchEvent( { type: 'dispose' } ); + + } + + } ); + + var count$3 = 0; + function GeometryIdCount() { return count$3++; } + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function DirectGeometry() { + + Object.defineProperty( this, 'id', { value: GeometryIdCount() } ); + + this.uuid = _Math.generateUUID(); + + this.name = ''; + this.type = '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, EventDispatcher.prototype, { + + computeBoundingBox: Geometry.prototype.computeBoundingBox, + computeBoundingSphere: Geometry.prototype.computeBoundingSphere, + + computeFaceNormals: function () { + + console.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' ); + + }, + + computeVertexNormals: function () { + + console.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' ); + + }, + + computeGroups: function ( geometry ) { + + var group; + var groups = []; + var materialIndex; + + 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; + + }, + + 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 }; + + } + + Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, { + + isBufferGeometry: true, + + getIndex: function () { + + return this.index; + + }, + + setIndex: function ( index ) { + + 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.applyToVector3Array( position.array ); + position.needsUpdate = true; + + } + + var normal = this.attributes.normal; + + if ( normal !== undefined ) { + + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + + normalMatrix.applyToVector3Array( normal.array ); + 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; + + return function rotateX( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationX( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + rotateY: function () { + + // rotate geometry around world y-axis + + var m1; + + return function rotateY( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationY( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + rotateZ: function () { + + // rotate geometry around world z-axis + + var m1; + + return function rotateZ( angle ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeRotationZ( angle ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + translate: function () { + + // translate geometry + + var m1; + + return function translate( x, y, z ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeTranslation( x, y, z ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + scale: function () { + + // scale geometry + + var m1; + + return function scale( x, y, z ) { + + if ( m1 === undefined ) m1 = new Matrix4(); + + m1.makeScale( x, y, z ); + + this.applyMatrix( m1 ); + + return this; + + }; + + }(), + + lookAt: function () { + + var obj; + + return function lookAt( vector ) { + + if ( obj === undefined ) obj = new Object3D(); + + 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 && object.isPoints) || (object && object.isLine) ) { + + var positions = new Float32Attribute( geometry.vertices.length * 3, 3 ); + var colors = new Float32Attribute( 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 Float32Attribute( 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 && object.isMesh) ) { + + if ( (geometry && geometry.isGeometry) ) { + + this.fromGeometry( geometry ); + + } + + } + + return this; + + }, + + updateFromObject: function ( object ) { + + var geometry = object.geometry; + + if ( (object && 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 = geometry.vertices.length > 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 Float32Attribute( morphTarget.length * 3, 3 ); + + array.push( attribute.copyVector3sArray( morphTarget ) ); + + } + + this.morphAttributes[ name ] = array; + + } + + // skinning + + if ( geometry.skinIndices.length > 0 ) { + + var skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 ); + this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); + + } + + if ( geometry.skinWeights.length > 0 ) { + + var skinWeights = new Float32Attribute( 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 positions = this.attributes.position.array; + + if ( positions !== undefined ) { + + this.boundingBox.setFromArray( positions ); + + } 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 positions = this.attributes.position; + + if ( positions ) { + + var array = positions.array; + var center = this.boundingSphere.center; + + box.setFromArray( array ); + 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 = array.length; i < il; i += 3 ) { + + vector.fromArray( array, 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, + + pA = new Vector3(), + pB = new Vector3(), + pC = new Vector3(), + + 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.array; + + var x, y, z, n; + + for ( var i = 0, il = normals.length; i < il; i += 3 ) { + + x = normals[ i ]; + y = normals[ i + 1 ]; + z = normals[ i + 2 ]; + + n = 1.0 / Math.sqrt( x * x + y * y + z * z ); + + normals[ i ] *= n; + normals[ i + 1 ] *= n; + normals[ i + 2 ] *= 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.4, + 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 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; + + }, + + dispose: function () { + + this.dispatchEvent( { type: 'dispose' } ); + + } + + } ); + + BufferGeometry.MaxIndex = 65535; + + /** + * @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, positions, uvs, a, b, c ) { + + vA.fromArray( positions, a * 3 ); + vB.fromArray( positions, b * 3 ); + vC.fromArray( positions, c * 3 ); + + var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint ); + + if ( intersection ) { + + if ( uvs ) { + + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); + + 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 uvs, intersection; + + if ( (geometry && geometry.isBufferGeometry) ) { + + var a, b, c; + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; + + if ( attributes.uv !== undefined ) { + + uvs = attributes.uv.array; + + } + + if ( index !== null ) { + + var indices = index.array; + + for ( var i = 0, l = indices.length; i < l; i += 3 ) { + + a = indices[ i ]; + b = indices[ i + 1 ]; + c = indices[ i + 2 ]; + + intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); + + if ( intersection ) { + + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics + intersects.push( intersection ); + + } + + } + + } else { + + + for ( var i = 0, l = positions.length; i < l; i += 9 ) { + + a = i / 3; + b = a + 1; + c = a + 2; + + intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); + + if ( intersection ) { + + intersection.index = a; // triangle number in positions buffer semantics + intersects.push( intersection ); + + } + + } + + } + + } else if ( (geometry && geometry.isGeometry) ) { + + var fvA, fvB, fvC; + var isFaceMaterial = (material && material.isMultiMaterial); + var materials = isFaceMaterial === true ? material.materials : null; + + var vertices = geometry.vertices; + var faces = geometry.faces; + 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 = isFaceMaterial === true ? materials[ 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 ) { + + 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 Mugen87 / https://github.com/Mugen87 + */ + + 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; + + // these are used to calculate buffer length + var vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments ); + var indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments ); + + // buffers + var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ); + var vertices = new Float32Array( vertexCount * 3 ); + var normals = new Float32Array( vertexCount * 3 ); + var uvs = new Float32Array( vertexCount * 2 ); + + // offset variables + var vertexBufferOffset = 0; + var uvBufferOffset = 0; + var indexBufferOffset = 0; + var numberOfVertices = 0; + + // group variables + 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( new BufferAttribute( indices, 1 ) ); + this.addAttribute( 'position', new BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) ); + + // helper functions + + function calculateVertexCount( w, h, d ) { + + var vertices = 0; + + // calculate the amount of vertices for each side (plane) + vertices += (w + 1) * (h + 1) * 2; // xy + vertices += (w + 1) * (d + 1) * 2; // xz + vertices += (d + 1) * (h + 1) * 2; // zy + + return vertices; + + } + + function calculateIndexCount( w, h, d ) { + + var index = 0; + + // calculate the amount of squares for each side + index += w * h * 2; // xy + index += w * d * 2; // xz + index += d * h * 2; // zy + + return index * 6; // two triangles per square => six vertices per square + + } + + 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 vector = new Vector3(); + + // generate vertices, normals and uvs + + for ( var iy = 0; iy < gridY1; iy ++ ) { + + var y = iy * segmentHeight - heightHalf; + + for ( var 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[ vertexBufferOffset ] = vector.x; + vertices[ vertexBufferOffset + 1 ] = vector.y; + vertices[ vertexBufferOffset + 2 ] = 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[ vertexBufferOffset ] = vector.x; + normals[ vertexBufferOffset + 1 ] = vector.y; + normals[ vertexBufferOffset + 2 ] = vector.z; + + // uvs + uvs[ uvBufferOffset ] = ix / gridX; + uvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY ); + + // update offsets and counters + vertexBufferOffset += 3; + uvBufferOffset += 2; + vertexCounter += 1; + + } + + } + + // 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 ++ ) { + + // indices + 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; + + // face one + indices[ indexBufferOffset ] = a; + indices[ indexBufferOffset + 1 ] = b; + indices[ indexBufferOffset + 2 ] = d; + + // face two + indices[ indexBufferOffset + 3 ] = b; + indices[ indexBufferOffset + 4 ] = c; + indices[ indexBufferOffset + 5 ] = d; + + // update offsets and counters + indexBufferOffset += 6; + 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/ + * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as + */ + + 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 vertices = new Float32Array( gridX1 * gridY1 * 3 ); + var normals = new Float32Array( gridX1 * gridY1 * 3 ); + var uvs = new Float32Array( gridX1 * gridY1 * 2 ); + + var offset = 0; + var offset2 = 0; + + for ( var iy = 0; iy < gridY1; iy ++ ) { + + var y = iy * segment_height - height_half; + + for ( var ix = 0; ix < gridX1; ix ++ ) { + + var x = ix * segment_width - width_half; + + vertices[ offset ] = x; + vertices[ offset + 1 ] = - y; + + normals[ offset + 2 ] = 1; + + uvs[ offset2 ] = ix / gridX; + uvs[ offset2 + 1 ] = 1 - ( iy / gridY ); + + offset += 3; + offset2 += 2; + + } + + } + + offset = 0; + + var indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 ); + + for ( var iy = 0; iy < gridY; iy ++ ) { + + for ( var 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; + + indices[ offset ] = a; + indices[ offset + 1 ] = b; + indices[ offset + 2 ] = d; + + indices[ offset + 3 ] = b; + indices[ offset + 4 ] = c; + indices[ offset + 5 ] = d; + + offset += 6; + + } + + } + + this.setIndex( new BufferAttribute( indices, 1 ) ); + this.addAttribute( 'position', new BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new BufferAttribute( 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.create( Object3D.prototype ); + Camera.prototype.constructor = Camera; + + Camera.prototype.isCamera = true; + + Camera.prototype.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 ); + + }; + + }(); + + Camera.prototype.lookAt = function () { + + // This routine does not support cameras with rotated and/or translated parent(s) + + var m1 = new Matrix4(); + + return function lookAt( vector ) { + + m1.lookAt( this.position, vector, this.up ); + + this.quaternion.setFromRotationMatrix( m1 ); + + }; + + }(); + + Camera.prototype.clone = function () { + + return new this.constructor().copy( this ); + + }; + + Camera.prototype.copy = function ( source ) { + + Object3D.prototype.copy.call( this, source ); + + this.matrixWorldInverse.copy( source.matrixWorldInverse ); + this.projectionMatrix.copy( source.projectionMatrix ); + + return 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.makeFrustum( + left, left + width, top - height, top, 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 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 { + + type = gl.UNSIGNED_SHORT; + size = 2; + + } + + } + + 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.WebGLBufferRenderer: 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; + + } + + return { + + setMode: setMode, + setIndex: setIndex, + render: render, + 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 ) { + + 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; + + var count = 0; + + if ( (position && position.isInterleavedBufferAttribute) ) { + + count = position.data.count; + + extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount ); + + } else { + + count = position.count; + + extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount ); + + } + + infoRender.calls ++; + infoRender.vertices += count * geometry.maxInstancedCount; + + if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3; + + } + + return { + setMode: setMode, + render: render, + renderInstances: renderInstances + }; + + } + + /** + * @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; + + } + + lights[ light.id ] = uniforms; + + return uniforms; + + } + + }; + + } + + /** + * @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_POINT_LIGHTS/g, parameters.numPointLights ) + .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ); + + } + + function parseIncludes( string ) { + + var pattern = /#include +<([\w\d.]+)>/g; + + 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.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.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.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', + 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", + "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", + "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", + "maxBones", "useVertexTexture", "morphTargets", "morphNormals", + "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", + "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", + "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking" + ]; + + + function allocateBones( object ) { + + if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { + + 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 = nVertexMatrices; + + if ( object !== undefined && (object && object.isSkinnedMesh) ) { + + maxBones = Math.min( object.skeleton.bones.length, maxBones ); + + if ( maxBones < object.skeleton.bones.length ) { + + console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' ); + + } + + } + + return maxBones; + + } + + } + + function getTextureEncodingFromMap( map, gammaOverrideLinear ) { + + var encoding; + + if ( ! map ) { + + encoding = LinearEncoding; + + } else if ( (map && map.isTexture) ) { + + encoding = map.encoding; + + } else if ( (map && 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 = allocateBones( object ); + 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.getCurrentRenderTarget(); + + 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, + + 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: maxBones, + useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture, + + morphTargets: material.morphTargets, + morphNormals: material.morphNormals, + maxMorphTargets: renderer.maxMorphTargets, + maxMorphNormals: renderer.maxMorphNormals, + + numDirLights: lights.directional.length, + numPointLights: lights.point.length, + numSpotLights: lights.spot.length, + numHemiLights: lights.hemi.length, + + numClippingPlanes: nClipPlanes, + numClipIntersection: nClipIntersection, + + 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 WebGLGeometries( gl, properties, info ) { + + var geometries = {}; + + function onGeometryDispose( event ) { + + var geometry = event.target; + var buffergeometry = geometries[ geometry.id ]; + + if ( buffergeometry.index !== null ) { + + deleteAttribute( buffergeometry.index ); + + } + + deleteAttributes( buffergeometry.attributes ); + + geometry.removeEventListener( 'dispose', onGeometryDispose ); + + delete geometries[ geometry.id ]; + + // TODO + + var property = properties.get( geometry ); + + if ( property.wireframe ) { + + deleteAttribute( property.wireframe ); + + } + + properties.delete( geometry ); + + var bufferproperty = properties.get( buffergeometry ); + + if ( bufferproperty.wireframe ) { + + deleteAttribute( bufferproperty.wireframe ); + + } + + properties.delete( buffergeometry ); + + // + + info.memory.geometries --; + + } + + function getAttributeBuffer( attribute ) { + + if ( attribute.isInterleavedBufferAttribute ) { + + return properties.get( attribute.data ).__webglBuffer; + + } + + return properties.get( attribute ).__webglBuffer; + + } + + function deleteAttribute( attribute ) { + + var buffer = getAttributeBuffer( attribute ); + + if ( buffer !== undefined ) { + + gl.deleteBuffer( buffer ); + removeAttributeBuffer( attribute ); + + } + + } + + function deleteAttributes( attributes ) { + + for ( var name in attributes ) { + + deleteAttribute( attributes[ name ] ); + + } + + } + + function removeAttributeBuffer( attribute ) { + + if ( attribute.isInterleavedBufferAttribute ) { + + properties.delete( attribute.data ); + + } else { + + properties.delete( attribute ); + + } + + } + + return { + + get: function ( object ) { + + var geometry = object.geometry; + + if ( geometries[ geometry.id ] !== undefined ) { + + return geometries[ geometry.id ]; + + } + + geometry.addEventListener( 'dispose', onGeometryDispose ); + + var buffergeometry; + + 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; + + info.memory.geometries ++; + + return buffergeometry; + + } + + }; + + } + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function WebGLObjects( gl, properties, info ) { + + var geometries = new WebGLGeometries( gl, properties, info ); + + // + + function update( object ) { + + // TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter. + + var geometry = geometries.get( object ); + + if ( object.geometry.isGeometry ) { + + geometry.updateFromObject( object ); + + } + + var index = geometry.index; + var attributes = geometry.attributes; + + if ( index !== null ) { + + updateAttribute( index, gl.ELEMENT_ARRAY_BUFFER ); + + } + + for ( var name in attributes ) { + + updateAttribute( attributes[ 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 ++ ) { + + updateAttribute( array[ i ], gl.ARRAY_BUFFER ); + + } + + } + + return geometry; + + } + + function updateAttribute( attribute, bufferType ) { + + var data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute; + + var attributeProperties = properties.get( data ); + + if ( attributeProperties.__webglBuffer === undefined ) { + + createBuffer( attributeProperties, data, bufferType ); + + } else if ( attributeProperties.version !== data.version ) { + + updateBuffer( attributeProperties, data, bufferType ); + + } + + } + + function createBuffer( attributeProperties, data, bufferType ) { + + attributeProperties.__webglBuffer = gl.createBuffer(); + gl.bindBuffer( bufferType, attributeProperties.__webglBuffer ); + + var usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW; + + gl.bufferData( bufferType, data.array, usage ); + + attributeProperties.version = data.version; + + } + + function updateBuffer( attributeProperties, data, bufferType ) { + + gl.bindBuffer( bufferType, attributeProperties.__webglBuffer ); + + if ( data.dynamic === false ) { + + gl.bufferData( bufferType, data.array, gl.STATIC_DRAW ); + + } else if ( data.updateRange.count === - 1 ) { + + // Not using update ranges + + gl.bufferSubData( bufferType, 0, data.array ); + + } else if ( data.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, data.updateRange.offset * data.array.BYTES_PER_ELEMENT, + data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) ); + + data.updateRange.count = 0; // reset range + + } + + attributeProperties.version = data.version; + + } + + function getAttributeBuffer( attribute ) { + + if ( attribute.isInterleavedBufferAttribute ) { + + return properties.get( attribute.data ).__webglBuffer; + + } + + return properties.get( attribute ).__webglBuffer; + + } + + function getWireframeAttribute( geometry ) { + + var property = properties.get( geometry ); + + if ( property.wireframe !== undefined ) { + + return property.wireframe; + + } + + var indices = []; + + var index = geometry.index; + var attributes = geometry.attributes; + var position = attributes.position; + + // console.time( 'wireframe' ); + + if ( index !== null ) { + + var edges = {}; + var array = index.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 = attributes.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' ); + + var TypeArray = position.count > 65535 ? Uint32Array : Uint16Array; + var attribute = new BufferAttribute( new TypeArray( indices ), 1 ); + + updateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER ); + + property.wireframe = attribute; + + return attribute; + + } + + return { + + getAttributeBuffer: getAttributeBuffer, + getWireframeAttribute: getWireframeAttribute, + + update: update + + }; + + } + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) { + + var _infoMemory = info.memory; + 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 ) { + + if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true; + if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true; + + return false; + + } + + // 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.delete( 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 && 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.delete( renderTarget.texture ); + properties.delete( 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 && 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; + + } + + // 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; + + } + + state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null ); + + } else if ( (texture && 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 && 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 && renderTarget.isWebGLRenderTargetCube) ); + + 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 && renderTarget.isWebGLRenderTargetCube) ); + 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 = {}; + + return { + + get: function ( object ) { + + var uuid = object.uuid; + var map = properties[ uuid ]; + + if ( map === undefined ) { + + map = {}; + properties[ uuid ] = map; + + } + + return map; + + }, + + delete: function ( object ) { + + delete properties[ object.uuid ]; + + }, + + clear: function () { + + properties = {}; + + } + + }; + + } + + /** + * @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 ) { + + 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 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() { + + clearColor( 0, 0, 0, 1 ); + clearDepth( 1 ); + clearStencil( 0 ); + + enable( gl.DEPTH_TEST ); + setDepthFunc( 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, extension ) { + + newAttributes[ attribute ] = 1; + + if ( enabledAttributes[ attribute ] === 0 ) { + + gl.enableVertexAttribArray( attribute ); + enabledAttributes[ attribute ] = 1; + + } + + if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { + + 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; + + } + + } + + // TODO Deprecate + + function setColorWrite( colorWrite ) { + + colorBuffer.setMask( colorWrite ); + + } + + function setDepthTest( depthTest ) { + + depthBuffer.setTest( depthTest ); + + } + + function setDepthWrite( depthWrite ) { + + depthBuffer.setMask( depthWrite ); + + } + + function setDepthFunc( depthFunc ) { + + depthBuffer.setFunc( depthFunc ); + + } + + function setStencilTest( stencilTest ) { + + stencilBuffer.setTest( stencilTest ); + + } + + function setStencilWrite( stencilWrite ) { + + stencilBuffer.setMask( stencilWrite ); + + } + + function setStencilFunc( stencilFunc, stencilRef, stencilMask ) { + + stencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask ); + + } + + function setStencilOp( stencilFail, stencilZFail, stencilZPass ) { + + stencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass ); + + } + + // + + 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 ) { + + 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 ); + + } + + } + + // TODO Deprecate + + function clearColor( r, g, b, a ) { + + colorBuffer.setClear( r, g, b, a ); + + } + + function clearDepth( depth ) { + + depthBuffer.setClear( depth ); + + } + + function clearStencil( stencil ) { + + stencilBuffer.setClear( stencil ); + + } + + // + + 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, + + setColorWrite: setColorWrite, + setDepthTest: setDepthTest, + setDepthWrite: setDepthWrite, + setDepthFunc: setDepthFunc, + setStencilTest: setStencilTest, + setStencilWrite: setStencilWrite, + setStencilFunc: setStencilFunc, + setStencilOp: setStencilOp, + + setFlipSided: setFlipSided, + setCullFace: setCullFace, + + setLineWidth: setLineWidth, + setPolygonOffset: setPolygonOffset, + + getScissorTest: getScissorTest, + setScissorTest: setScissorTest, + + activeTexture: activeTexture, + bindTexture: bindTexture, + compressedTexImage2D: compressedTexImage2D, + texImage2D: texImage2D, + + clearColor: clearColor, + clearDepth: clearDepth, + clearStencil: clearStencil, + + 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; + + } + + } + + /** + * @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 opaqueObjects = []; + var opaqueObjectsLastIndex = - 1; + var transparentObjects = []; + var transparentObjectsLastIndex = - 1; + + 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, + + _sphere = new Sphere(), + + // camera matrices cache + + _projScreenMatrix = new Matrix4(), + + _vector3 = new Vector3(), + + // light arrays cache + + _lights = { + + hash: '', + + ambient: [ 0, 0, 0 ], + directional: [], + directionalShadowMap: [], + directionalShadowMatrix: [], + spot: [], + spotShadowMap: [], + spotShadowMatrix: [], + point: [], + pointShadowMap: [], + pointShadowMatrix: [], + hemi: [], + + shadows: [] + + }, + + // info + + _infoRender = { + + calls: 0, + vertices: 0, + faces: 0, + points: 0 + + }; + + this.info = { + + render: _infoRender, + memory: { + + geometries: 0, + textures: 0 + + }, + programs: null + + }; + + + // initialize + + var _gl; + + try { + + var attributes = { + alpha: _alpha, + depth: _depth, + stencil: _stencil, + antialias: _antialias, + premultipliedAlpha: _premultipliedAlpha, + preserveDrawingBuffer: _preserveDrawingBuffer + }; + + _gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes ); + + 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, this.info ); + var objects = new WebGLObjects( _gl, properties, this.info ); + var programCache = new WebGLPrograms( this, capabilities ); + var lightCache = new WebGLLights(); + + this.info.programs = programCache.programs; + + var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender ); + var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender ); + + // + + var backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + var backgroundCamera2 = new PerspectiveCamera(); + var backgroundPlaneMesh = new Mesh( + new PlaneBufferGeometry( 2, 2 ), + new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } ) + ); + var backgroundBoxShader = ShaderLib[ 'cube' ]; + var backgroundBoxMesh = new Mesh( + new BoxBufferGeometry( 5, 5, 5 ), + new ShaderMaterial( { + uniforms: backgroundBoxShader.uniforms, + vertexShader: backgroundBoxShader.vertexShader, + fragmentShader: backgroundBoxShader.fragmentShader, + side: BackSide, + depthTest: false, + depthWrite: false, + fog: false + } ) + ); + + // + + function getTargetPixelRatio() { + + return _currentRenderTarget === null ? _pixelRatio : 1; + + } + + function glClearColor( r, g, b, a ) { + + if ( _premultipliedAlpha === true ) { + + r *= a; g *= a; b *= a; + + } + + state.clearColor( r, g, b, a ); + + } + + function setDefaultGLState() { + + state.init(); + + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); + + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + } + + 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 () { + + extensions.get( 'WEBGL_lose_context' ).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; + + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + }; + + this.getClearAlpha = function () { + + return _clearAlpha; + + }; + + this.setClearAlpha = function ( alpha ) { + + _clearAlpha = alpha; + + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + }; + + 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() { + + transparentObjects = []; + transparentObjectsLastIndex = -1; + opaqueObjects = []; + opaqueObjectsLastIndex = -1; + + _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); + + }; + + // Events + + function onContextLost( event ) { + + event.preventDefault(); + + resetGLState(); + setDefaultGLState(); + + properties.clear(); + + } + + function onMaterialDispose( event ) { + + var material = event.target; + + material.removeEventListener( 'dispose', onMaterialDispose ); + + deallocateMaterial( material ); + + } + + // Buffer deallocation + + function deallocateMaterial( material ) { + + releaseMaterialProgramReference( material ); + + properties.delete( material ); + + } + + + function releaseMaterialProgramReference( material ) { + + var programInfo = properties.get( material ).program; + + material.program = undefined; + + if ( programInfo !== undefined ) { + + programCache.releaseProgram( programInfo ); + + } + + } + + // Buffer rendering + + 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 attributes = program.getAttributes(); + + if ( object.hasPositions ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); + + state.enableAttribute( attributes.position ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); + + } + + if ( object.hasNormals ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); + + if ( ! material.isMeshPhongMaterial && + ! material.isMeshStandardMaterial && + 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( attributes.normal ); + + _gl.vertexAttribPointer( attributes.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( attributes.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( attributes.color ); + + _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 ); + + } + + state.disableUnusedAttributes(); + + _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); + + object.count = 0; + + }; + + this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { + + setMaterial( material ); + + var program = setProgram( camera, fog, material, object ); + + var updateBuffers = false; + var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe; + + if ( geometryProgram !== _currentGeometryProgram ) { + + _currentGeometryProgram = geometryProgram; + updateBuffers = true; + + } + + // morph targets + + var morphTargetInfluences = object.morphTargetInfluences; + + if ( morphTargetInfluences !== undefined ) { + + 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 = objects.getWireframeAttribute( geometry ); + rangeFactor = 2; + + } + + var renderer; + + if ( index !== null ) { + + renderer = indexedBufferRenderer; + renderer.setIndex( index ); + + } else { + + renderer = bufferRenderer; + + } + + if ( updateBuffers ) { + + setupVertexAttributes( material, program, geometry ); + + if ( index !== null ) { + + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) ); + + } + + } + + // + + 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 { + + 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 ) { + + var extension; + + if ( geometry && geometry.isInstancedBufferGeometry ) { + + extension = extensions.get( 'ANGLE_instanced_arrays' ); + + if ( extension === 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 type = _gl.FLOAT; + var array = geometryAttribute.array; + var normalized = geometryAttribute.normalized; + + 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; + + } + + var size = geometryAttribute.itemSize; + var buffer = objects.getAttributeBuffer( geometryAttribute ); + + if ( geometryAttribute.isInterleavedBufferAttribute ) { + + var data = geometryAttribute.data; + var stride = data.stride; + var offset = geometryAttribute.offset; + + if ( data && data.isInstancedInterleavedBuffer ) { + + state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension ); + + 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 * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT ); + + } else { + + if ( geometryAttribute.isInstancedBufferAttribute ) { + + state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension ); + + 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 * geometryAttribute.array.BYTES_PER_ELEMENT ); + + } + + } 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(); + + } + + // Sorting + + function absNumericalSort( a, b ) { + + return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] ); + + } + + function painterSortStable( a, b ) { + + if ( a.object.renderOrder !== b.object.renderOrder ) { + + return a.object.renderOrder - b.object.renderOrder; + + } else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) { + + return a.material.program.id - b.material.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.object.renderOrder !== b.object.renderOrder ) { + + return a.object.renderOrder - b.object.renderOrder; + + } if ( a.z !== b.z ) { + + return b.z - a.z; + + } else { + + return a.id - b.id; + + } + + } + + // 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 + + if ( camera.parent === null ) camera.updateMatrixWorld(); + + camera.matrixWorldInverse.getInverse( camera.matrixWorld ); + + _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + _frustum.setFromMatrix( _projScreenMatrix ); + + lights.length = 0; + + opaqueObjectsLastIndex = - 1; + transparentObjectsLastIndex = - 1; + + sprites.length = 0; + lensFlares.length = 0; + + _localClippingEnabled = this.localClippingEnabled; + _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); + + projectObject( scene, camera ); + + opaqueObjects.length = opaqueObjectsLastIndex + 1; + transparentObjects.length = transparentObjectsLastIndex + 1; + + if ( _this.sortObjects === true ) { + + opaqueObjects.sort( painterSortStable ); + transparentObjects.sort( reversePainterSortStable ); + + } + + // + + if ( _clippingEnabled ) _clipping.beginShadows(); + + setupShadows( lights ); + + shadowMap.render( scene, camera ); + + setupLights( lights, camera ); + + if ( _clippingEnabled ) _clipping.endShadows(); + + // + + _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 ) { + + glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + } else if ( background && background.isColor ) { + + glClearColor( background.r, background.g, background.b, 1 ); + forceClear = true; + + } + + if ( this.autoClear || forceClear ) { + + this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil ); + + } + + if ( background && background.isCubeTexture ) { + + backgroundCamera2.projectionMatrix.copy( camera.projectionMatrix ); + + backgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld ); + backgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld ); + + backgroundBoxMesh.material.uniforms[ "tCube" ].value = background; + backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld ); + + objects.update( backgroundBoxMesh ); + + _this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null ); + + } else if ( background && background.isTexture ) { + + backgroundPlaneMesh.material.map = background; + + objects.update( backgroundPlaneMesh ); + + _this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null ); + + } + + // + + if ( scene.overrideMaterial ) { + + var overrideMaterial = scene.overrideMaterial; + + renderObjects( opaqueObjects, scene, camera, overrideMaterial ); + renderObjects( transparentObjects, scene, camera, overrideMaterial ); + + } else { + + // opaque pass (front-to-back order) + + state.setBlending( NoBlending ); + renderObjects( opaqueObjects, scene, camera ); + + // transparent pass (back-to-front order) + + 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.setDepthTest( true ); + state.setDepthWrite( true ); + state.setColorWrite( true ); + + // _gl.finish(); + + }; + + function pushRenderItem( object, geometry, material, z, group ) { + + var array, index; + + // allocate the next position in the appropriate array + + if ( material.transparent ) { + + array = transparentObjects; + index = ++ transparentObjectsLastIndex; + + } else { + + array = opaqueObjects; + index = ++ opaqueObjectsLastIndex; + + } + + // recycle existing render item or grow the array + + var renderItem = array[ index ]; + + if ( renderItem !== undefined ) { + + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.z = _vector3.z; + renderItem.group = group; + + } else { + + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + z: _vector3.z, + group: group + }; + + // assert( index === array.length ); + array.push( renderItem ); + + } + + } + + // TODO Duplicated code (Frustum) + + 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 ) { + + if ( object.visible === false ) return; + + var visible = ( object.layers.mask & camera.layers.mask ) !== 0; + + if ( visible ) { + + if ( object.isLight ) { + + lights.push( object ); + + } else if ( object.isSprite ) { + + if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) { + + sprites.push( object ); + + } + + } else if ( object.isLensFlare ) { + + lensFlares.push( object ); + + } else if ( object.isImmediateRenderObject ) { + + if ( _this.sortObjects === true ) { + + _vector3.setFromMatrixPosition( object.matrixWorld ); + _vector3.applyProjection( _projScreenMatrix ); + + } + + pushRenderItem( object, null, object.material, _vector3.z, null ); + + } else if ( object.isMesh || object.isLine || object.isPoints ) { + + if ( object.isSkinnedMesh ) { + + object.skeleton.update(); + + } + + if ( object.frustumCulled === false || isObjectViewable( object ) === true ) { + + var material = object.material; + + if ( material.visible === true ) { + + if ( _this.sortObjects === true ) { + + _vector3.setFromMatrixPosition( object.matrixWorld ); + _vector3.applyProjection( _projScreenMatrix ); + + } + + var geometry = objects.update( object ); + + if ( material.isMultiMaterial ) { + + var groups = geometry.groups; + var materials = material.materials; + + for ( var i = 0, l = groups.length; i < l; i ++ ) { + + var group = groups[ i ]; + var groupMaterial = materials[ group.materialIndex ]; + + if ( groupMaterial.visible === true ) { + + pushRenderItem( object, geometry, groupMaterial, _vector3.z, group ); + + } + + } + + } else { + + pushRenderItem( object, geometry, material, _vector3.z, null ); + + } + + } + + } + + } + + } + + var children = object.children; + + for ( var i = 0, l = children.length; i < l; i ++ ) { + + projectObject( children[ i ], camera ); + + } + + } + + 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.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); + object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); + + object.onBeforeRender( _this, scene, camera, geometry, material, group ); + + if ( object.isImmediateRenderObject ) { + + setMaterial( material ); + + var program = setProgram( camera, scene.fog, material, object ); + + _currentGeometryProgram = ''; + + object.render( function ( object ) { + + _this.renderBufferImmediate( object, program, material ); + + } ); + + } else { + + _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); + + } + + object.onAfterRender( _this, scene, camera, geometry, material, 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 attributes = program.getAttributes(); + + if ( material.morphTargets ) { + + material.numSupportedMorphTargets = 0; + + for ( var i = 0; i < _this.maxMorphTargets; i ++ ) { + + if ( attributes[ 'morphTarget' + i ] >= 0 ) { + + material.numSupportedMorphTargets ++; + + } + + } + + } + + if ( material.morphNormals ) { + + material.numSupportedMorphNormals = 0; + + for ( var i = 0; i < _this.maxMorphNormals; i ++ ) { + + if ( attributes[ '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.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; + + } + + var progUniforms = materialProperties.program.getUniforms(), + uniformsList = + WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); + + materialProperties.uniformsList = uniformsList; + + } + + function setMaterial( material ) { + + material.side === DoubleSide + ? state.disable( _gl.CULL_FACE ) + : state.enable( _gl.CULL_FACE ); + + state.setFlipSided( material.side === BackSide ); + + material.transparent === true + ? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ) + : state.setBlending( NoBlending ); + + state.setDepthFunc( material.depthFunc ); + state.setDepthTest( material.depthTest ); + state.setDepthWrite( material.depthWrite ); + state.setColorWrite( material.colorWrite ); + state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + + } + + 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.set( _gl, 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.set( _gl, _this, 'toneMappingExposure' ); + p_uniforms.set( _gl, _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 ) { + + if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) { + + p_uniforms.set( _gl, skeleton, 'boneTexture' ); + p_uniforms.set( _gl, skeleton, 'boneTextureWidth' ); + p_uniforms.set( _gl, skeleton, 'boneTextureHeight' ); + + } 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.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.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 ) { + + m_uniforms.opacity.value = material.opacity; + + } + + WebGLUniforms.upload( + _gl, materialProperties.uniformsList, m_uniforms, _this ); + + } + + + // common matrices + + p_uniforms.set( _gl, object, 'modelViewMatrix' ); + p_uniforms.set( _gl, 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.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.lightMap ) { + + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; + + } + + 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.lightMap ) { + + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; + + } + + 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 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.lightMap ) { + + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; + + } + + 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 ); + + } + + // 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.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; + + } + + } + + _lights.shadows.length = lightShadowsLength; + + } + + function setupLights( lights, camera ) { + + var l, ll, light, + r = 0, g = 0, b = 0, + color, + intensity, + distance, + shadowMap, + + viewMatrix = camera.matrixWorldInverse, + + directionalLength = 0, + pointLength = 0, + spotLength = 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 ) { + + uniforms.shadowBias = light.shadow.bias; + uniforms.shadowRadius = light.shadow.radius; + uniforms.shadowMapSize = light.shadow.mapSize; + + } + + _lights.directionalShadowMap[ directionalLength ] = shadowMap; + _lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; + _lights.directional[ directionalLength ++ ] = uniforms; + + } 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 ) { + + uniforms.shadowBias = light.shadow.bias; + uniforms.shadowRadius = light.shadow.radius; + uniforms.shadowMapSize = light.shadow.mapSize; + + } + + _lights.spotShadowMap[ spotLength ] = shadowMap; + _lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix; + _lights.spot[ spotLength ++ ] = uniforms; + + } 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 ) { + + uniforms.shadowBias = light.shadow.bias; + uniforms.shadowRadius = light.shadow.radius; + uniforms.shadowMapSize = light.shadow.mapSize; + + } + + _lights.pointShadowMap[ pointLength ] = shadowMap; + + if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) { + + _lights.pointShadowMatrix[ pointLength ] = new Matrix4(); + + } + + // for point lights we set the shadow matrix to be a translation-only matrix + // equal to inverse of the light's position + _vector3.setFromMatrixPosition( light.matrixWorld ).negate(); + _lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 ); + + _lights.point[ pointLength ++ ] = uniforms; + + } 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; + + } + + } + + _lights.ambient[ 0 ] = r; + _lights.ambient[ 1 ] = g; + _lights.ambient[ 2 ] = b; + + _lights.directional.length = directionalLength; + _lights.spot.length = spotLength; + _lights.point.length = pointLength; + _lights.hemi.length = hemiLength; + + _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + 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.getCurrentRenderTarget = 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.create( Object3D.prototype ); + + Scene.prototype.constructor = Scene; + + Scene.prototype.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; + + }; + + Scene.prototype.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: , + * opacity: , + * map: new THREE.Texture( ), + * + * 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.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 matrixPosition = new Vector3(); + + return function raycast( raycaster, intersects ) { + + matrixPosition.setFromMatrixPosition( this.matrixWorld ); + + var distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition ); + var guessSizeSq = this.scale.x * this.scale.y / 4; + + if ( distanceSq > guessSizeSq ) { + + return; + + } + + intersects.push( { + + distance: Math.sqrt( distanceSq ), + point: this.position, + 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 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 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, useVertexTexture ) { + + this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true; + + this.identityMatrix = new Matrix4(); + + // copy the bone array + + bones = bones || []; + + this.bones = bones.slice( 0 ); + + // create a bone texture or an array of floats + + if ( this.useVertexTexture ) { + + // 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( this.bones.length * 4 ); // 4 pixels needed for 1 matrix + size = _Math.nextPowerOfTwo( Math.ceil( size ) ); + size = Math.max( size, 4 ); + + this.boneTextureWidth = size; + this.boneTextureHeight = size; + + this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel + this.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType ); + + } else { + + this.boneMatrices = new Float32Array( 16 * this.bones.length ); + + } + + // 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 bonInverses is the wrong length.' ); + + this.boneInverses = []; + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + this.boneInverses.push( new Matrix4() ); + + } + + } + + } + + } + + Object.assign( Skeleton.prototype, { + + calculateInverses: function () { + + this.boneInverses = []; + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + var inverse = new Matrix4(); + + if ( this.bones[ b ] ) { + + inverse.getInverse( this.bones[ b ].matrixWorld ); + + } + + this.boneInverses.push( inverse ); + + } + + }, + + pose: function () { + + var bone; + + // recover the bind-time world matrices + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + bone = this.bones[ b ]; + + if ( bone ) { + + bone.matrixWorld.getInverse( this.boneInverses[ b ] ); + + } + + } + + // compute the local matrices, positions, rotations and scales + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + bone = this.bones[ b ]; + + 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(); + + return function update() { + + // flatten bone matrices to array + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + // compute the offset between the current and the original transform + + var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix; + + offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] ); + offsetMatrix.toArray( this.boneMatrices, b * 16 ); + + } + + if ( this.useVertexTexture ) { + + this.boneTexture.needsUpdate = true; + + } + + }; + + } )(), + + clone: function () { + + return new Skeleton( this.bones, this.boneInverses, this.useVertexTexture ); + + } + + } ); + + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author ikerr / http://verold.com + */ + + function Bone( skin ) { + + Object3D.call( this ); + + this.type = 'Bone'; + + this.skin = skin; + + } + + Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { + + constructor: Bone, + + isBone: true, + + copy: function ( source ) { + + Object3D.prototype.copy.call( this, source ); + + this.skin = source.skin; + + return this; + + } + + } ); + + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author ikerr / http://verold.com + */ + + function SkinnedMesh( geometry, material, useVertexTexture ) { + + Mesh.call( this, geometry, material ); + + this.type = 'SkinnedMesh'; + + this.bindMode = "attached"; + this.bindMatrix = new Matrix4(); + this.bindMatrixInverse = new Matrix4(); + + // init bones + + // TODO: remove bone creation as there is no reason (other than + // convenience) for THREE.SkinnedMesh to do this. + + var bones = []; + + if ( this.geometry && this.geometry.bones !== undefined ) { + + var bone, gbone; + + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { + + gbone = this.geometry.bones[ b ]; + + bone = new Bone( this ); + bones.push( bone ); + + bone.name = gbone.name; + bone.position.fromArray( gbone.pos ); + bone.quaternion.fromArray( gbone.rotq ); + if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl ); + + } + + for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) { + + gbone = this.geometry.bones[ b ]; + + if ( gbone.parent !== - 1 && gbone.parent !== null && + bones[ gbone.parent ] !== undefined ) { + + bones[ gbone.parent ].add( bones[ b ] ); + + } else { + + this.add( bones[ b ] ); + + } + + } + + } + + this.normalizeSkinWeights(); + + this.updateMatrixWorld( true ); + this.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld ); + + } + + + SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { + + constructor: SkinnedMesh, + + isSkinnedMesh: true, + + 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 () { + + if ( (this.geometry && this.geometry.isGeometry) ) { + + for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) { + + var sw = this.geometry.skinWeights[ i ]; + + var 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 ( var 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 ); + + var 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, true ); + + 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, this.skeleton.useVertexTexture ).copy( this ); + + } + + } ); + + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * + * linewidth: , + * 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 && 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 && 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 mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * size: , + * sizeAttenuation: + * } + */ + + 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 ); + + 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 && 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' ) + + } + + Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + + this.image = { width: width, height: height }; + + this.type = type !== undefined ? type : UnsignedShortType; + + 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/ + */ + + function WireframeGeometry( geometry ) { + + BufferGeometry.call( this ); + + var edge = [ 0, 0 ], hash = {}; + + function sortFunction( a, b ) { + + return a - b; + + } + + var keys = [ 'a', 'b', 'c' ]; + + if ( (geometry && geometry.isGeometry) ) { + + var vertices = geometry.vertices; + var faces = geometry.faces; + var numEdges = 0; + + // allocate maximal size + var edges = new Uint32Array( 6 * faces.length ); + + for ( var i = 0, l = faces.length; i < l; i ++ ) { + + var face = faces[ i ]; + + for ( var j = 0; j < 3; j ++ ) { + + edge[ 0 ] = face[ keys[ j ] ]; + edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ]; + edge.sort( sortFunction ); + + var key = edge.toString(); + + if ( hash[ key ] === undefined ) { + + edges[ 2 * numEdges ] = edge[ 0 ]; + edges[ 2 * numEdges + 1 ] = edge[ 1 ]; + hash[ key ] = true; + numEdges ++; + + } + + } + + } + + var coords = new Float32Array( numEdges * 2 * 3 ); + + for ( var i = 0, l = numEdges; i < l; i ++ ) { + + for ( var j = 0; j < 2; j ++ ) { + + var vertex = vertices[ edges [ 2 * i + j ] ]; + + var index = 6 * i + 3 * j; + coords[ index + 0 ] = vertex.x; + coords[ index + 1 ] = vertex.y; + coords[ index + 2 ] = vertex.z; + + } + + } + + this.addAttribute( 'position', new BufferAttribute( coords, 3 ) ); + + } else if ( (geometry && geometry.isBufferGeometry) ) { + + if ( geometry.index !== null ) { + + // Indexed BufferGeometry + + var indices = geometry.index.array; + var vertices = geometry.attributes.position; + var groups = geometry.groups; + var numEdges = 0; + + if ( groups.length === 0 ) { + + geometry.addGroup( 0, indices.length ); + + } + + // allocate maximal size + var edges = new Uint32Array( 2 * indices.length ); + + for ( var o = 0, ol = groups.length; o < ol; ++ o ) { + + var group = groups[ o ]; + + var start = group.start; + var count = group.count; + + for ( var i = start, il = start + count; i < il; i += 3 ) { + + for ( var j = 0; j < 3; j ++ ) { + + edge[ 0 ] = indices[ i + j ]; + edge[ 1 ] = indices[ i + ( j + 1 ) % 3 ]; + edge.sort( sortFunction ); + + var key = edge.toString(); + + if ( hash[ key ] === undefined ) { + + edges[ 2 * numEdges ] = edge[ 0 ]; + edges[ 2 * numEdges + 1 ] = edge[ 1 ]; + hash[ key ] = true; + numEdges ++; + + } + + } + + } + + } + + var coords = new Float32Array( numEdges * 2 * 3 ); + + for ( var i = 0, l = numEdges; i < l; i ++ ) { + + for ( var j = 0; j < 2; j ++ ) { + + var index = 6 * i + 3 * j; + var index2 = edges[ 2 * i + j ]; + + coords[ index + 0 ] = vertices.getX( index2 ); + coords[ index + 1 ] = vertices.getY( index2 ); + coords[ index + 2 ] = vertices.getZ( index2 ); + + } + + } + + this.addAttribute( 'position', new BufferAttribute( coords, 3 ) ); + + } else { + + // non-indexed BufferGeometry + + var vertices = geometry.attributes.position.array; + var numEdges = vertices.length / 3; + var numTris = numEdges / 3; + + var coords = new Float32Array( numEdges * 2 * 3 ); + + for ( var i = 0, l = numTris; i < l; i ++ ) { + + for ( var j = 0; j < 3; j ++ ) { + + var index = 18 * i + 6 * j; + + var index1 = 9 * i + 3 * j; + coords[ index + 0 ] = vertices[ index1 ]; + coords[ index + 1 ] = vertices[ index1 + 1 ]; + coords[ index + 2 ] = vertices[ index1 + 2 ]; + + var index2 = 9 * i + 3 * ( ( j + 1 ) % 3 ); + coords[ index + 3 ] = vertices[ index2 ]; + coords[ index + 4 ] = vertices[ index2 + 1 ]; + coords[ index + 5 ] = vertices[ index2 + 2 ]; + + } + + } + + this.addAttribute( 'position', new BufferAttribute( coords, 3 ) ); + + } + + } + + } + + WireframeGeometry.prototype = Object.create( BufferGeometry.prototype ); + WireframeGeometry.prototype.constructor = WireframeGeometry; + + /** + * @author Mugen87 / https://github.com/Mugen87 + * + * Parametric Surfaces Geometry + * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 + */ + + function ParametricBufferGeometry( func, slices, stacks ) { + + BufferGeometry.call( this ); + + this.type = 'ParametricBufferGeometry'; + + this.parameters = { + func: func, + slices: slices, + stacks: stacks + }; + + // generate vertices and uvs + + var vertices = []; + var uvs = []; + + var i, j, p; + var u, v; + + var sliceCount = slices + 1; + + for ( i = 0; i <= stacks; i ++ ) { + + v = i / stacks; + + for ( j = 0; j <= slices; j ++ ) { + + u = j / slices; + + p = func( u, v ); + vertices.push( p.x, p.y, p.z ); + + uvs.push( u, v ); + + } + + } + + // generate indices + + var indices = []; + var a, b, c, d; + + for ( i = 0; i < stacks; i ++ ) { + + for ( j = 0; j < slices; j ++ ) { + + a = i * sliceCount + j; + b = i * sliceCount + j + 1; + c = ( i + 1 ) * sliceCount + j + 1; + d = ( i + 1 ) * sliceCount + j; + + // faces one and two + + indices.push( a, b, d ); + indices.push( b, c, d ); + + } + + } + + // build geometry + + this.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) ); + this.addAttribute( 'position', Float32Attribute( vertices, 3 ) ); + this.addAttribute( 'uv', Float32Attribute( uvs, 2 ) ); + + // generate normals + + this.computeVertexNormals(); + + } + + ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; + + /** + * @author zz85 / https://github.com/zz85 + * + * Parametric Surfaces Geometry + * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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', Float32Attribute( vertexBuffer, 3 ) ); + this.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) ); + this.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) ); + this.normalizeNormals(); + + this.boundingSphere = new Sphere( new Vector3(), radius ); + + // 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 Mugen87 / https://github.com/Mugen87 + */ + + 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 + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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 + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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 timothypratley / https://github.com/timothypratley + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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 Abe Pazos / https://hamoid.com + */ + + 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; + + /** + * @author clockworkgeek / https://github.com/clockworkgeek + * @author timothypratley / https://github.com/timothypratley + * @author WestLangley / http://github.com/WestLangley + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + * + * Creates a tube which extrudes along a 3d spline. + * + */ + + 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.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) ); + this.addAttribute( 'position', Float32Attribute( vertices, 3 ) ); + this.addAttribute( 'normal', Float32Attribute( normals, 3 ) ); + this.addAttribute( 'uv', Float32Attribute( 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 / 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 + * + * Creates a tube which extrudes along a 3d spline. + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + * + * see: http://www.blackpawn.com/texts/pqtorus/ + */ + 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; + + // used to calculate buffer length + var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) ); + var indexCount = radialSegments * tubularSegments * 2 * 3; + + // buffers + var indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + var i, j, index = 0, indexOffset = 0; + + var vertex = new Vector3(); + var normal = new Vector3(); + var uv = new Vector2(); + + 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 ); + + // vertex + vertices.setXYZ( index, 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.setXYZ( index, normal.x, normal.y, normal.z ); + + // uv + uv.x = i / tubularSegments; + uv.y = j / radialSegments; + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + } + + // 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; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + // face two + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + // 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 + */ + + 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; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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; + + // used to calculate buffer length + var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) ); + var indexCount = radialSegments * tubularSegments * 2 * 3; + + // buffers + var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ); + var vertices = new Float32Array( vertexCount * 3 ); + var normals = new Float32Array( vertexCount * 3 ); + var uvs = new Float32Array( vertexCount * 2 ); + + // offset variables + var vertexBufferOffset = 0; + var uvBufferOffset = 0; + var indexBufferOffset = 0; + + // 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[ vertexBufferOffset ] = vertex.x; + vertices[ vertexBufferOffset + 1 ] = vertex.y; + vertices[ vertexBufferOffset + 2 ] = vertex.z; + + // this vector is used to calculate the normal + center.x = radius * Math.cos( u ); + center.y = radius * Math.sin( u ); + + // normal + normal.subVectors( vertex, center ).normalize(); + + normals[ vertexBufferOffset ] = normal.x; + normals[ vertexBufferOffset + 1 ] = normal.y; + normals[ vertexBufferOffset + 2 ] = normal.z; + + // uv + uvs[ uvBufferOffset ] = i / tubularSegments; + uvs[ uvBufferOffset + 1 ] = j / radialSegments; + + // update offsets + vertexBufferOffset += 3; + uvBufferOffset += 2; + + } + + } + + // 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; + + // face one + indices[ indexBufferOffset ] = a; + indices[ indexBufferOffset + 1 ] = b; + indices[ indexBufferOffset + 2 ] = d; + + // face two + indices[ indexBufferOffset + 3 ] = b; + indices[ indexBufferOffset + 4 ] = c; + indices[ indexBufferOffset + 5 ] = d; + + // update offset + indexBufferOffset += 6; + + } + + } + + // build geometry + this.setIndex( new BufferAttribute( indices, 1 ) ); + this.addAttribute( 'position', new BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) ); + + } + + TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + TorusBufferGeometry.prototype.constructor = TorusBufferGeometry; + + /** + * @author oosmoxiecode + * @author mrdoob / http://mrdoob.com/ + * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888 + */ + + 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 ) ); + + } + + TorusGeometry.prototype = Object.create( Geometry.prototype ); + TorusGeometry.prototype.constructor = TorusGeometry; + + /** + * @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; 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; + + }, + + // Bezier Curves formulas obtained from + // http://en.wikipedia.org/wiki/B%C3%A9zier_curve + + // Quad Bezier Functions + + b2: ( function () { + + function b2p0( t, p ) { + + var k = 1 - t; + return k * k * p; + + } + + function b2p1( t, p ) { + + return 2 * ( 1 - t ) * t * p; + + } + + function b2p2( t, p ) { + + return t * t * p; + + } + + return function b2( t, p0, p1, p2 ) { + + return b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 ); + + }; + + } )(), + + // Cubic Bezier Functions + + b3: ( function () { + + function b3p0( t, p ) { + + var k = 1 - t; + return k * k * k * p; + + } + + function b3p1( t, p ) { + + var k = 1 - t; + return 3 * k * k * t * p; + + } + + function b3p2( t, p ) { + + var k = 1 - t; + return 3 * k * t * t * p; + + } + + function b3p3( t, p ) { + + return t * t * t * p; + + } + + return function b3( t, p0, p1, p2, p3 ) { + + return b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 ); + + }; + + } )() + + }; + + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * + * Creates extruded geometry from a path shape. + * + * parameters = { + * + * curveSegments: , // number of points on the curves + * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too + * amount: , // Depth to extrude the shape + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into the original shape bevel goes + * bevelSize: , // how far from shape outline is bevel + * bevelSegments: , // number of bevel layers + * + * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined) + * frames: // containing arrays of tangents, normals, binormals + * + * uvGenerator: // object that provides UV generator functions + * + * } + **/ + + function ExtrudeGeometry( shapes, options ) { + + if ( typeof( shapes ) === "undefined" ) { + + shapes = []; + return; + + } + + Geometry.call( this ); + + this.type = 'ExtrudeGeometry'; + + shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; + + this.addShapeList( shapes, options ); + + this.computeFaceNormals(); + + // 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 ) ); + + } + + ExtrudeGeometry.prototype = Object.create( Geometry.prototype ); + ExtrudeGeometry.prototype.constructor = ExtrudeGeometry; + + ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) { + + var sl = shapes.length; + + for ( var s = 0; s < sl; s ++ ) { + + var shape = shapes[ s ]; + this.addShape( shape, options ); + + } + + }; + + ExtrudeGeometry.prototype.addShape = function ( shape, options ) { + + 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 shapesOffset = this.vertices.length; + + 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() { + + 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 ); + + } + + } + + } + + // Create faces for the z-sides of the shape + + function buildSideFaces() { + + 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; + + } + + } + + 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 ) { + + scope.vertices.push( new Vector3( x, y, z ) ); + + } + + function f3( a, b, c ) { + + a += shapesOffset; + b += shapesOffset; + c += shapesOffset; + + scope.faces.push( new Face3( a, b, c, null, null, 0 ) ); + + var uvs = uvgen.generateTopUV( scope, a, b, c ); + + scope.faceVertexUvs[ 0 ].push( uvs ); + + } + + function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) { + + a += shapesOffset; + b += shapesOffset; + c += shapesOffset; + d += shapesOffset; + + scope.faces.push( new Face3( a, b, d, null, null, 1 ) ); + scope.faces.push( new Face3( b, c, d, null, null, 1 ) ); + + var uvs = uvgen.generateSideWallUV( scope, a, b, c, d ); + + scope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] ); + scope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] ); + + } + + }; + + ExtrudeGeometry.WorldUVGenerator = { + + generateTopUV: function ( geometry, indexA, indexB, indexC ) { + + var vertices = geometry.vertices; + + var a = vertices[ indexA ]; + var b = vertices[ indexB ]; + var c = vertices[ indexC ]; + + return [ + new Vector2( a.x, a.y ), + new Vector2( b.x, b.y ), + new Vector2( c.x, c.y ) + ]; + + }, + + generateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) { + + var vertices = geometry.vertices; + + var a = vertices[ indexA ]; + var b = vertices[ indexB ]; + var c = vertices[ indexC ]; + var d = vertices[ indexD ]; + + 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: , // font + * + * size: , // size of the text + * height: , // thickness to extrude text + * curveSegments: , // number of points on the curves + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into text bevel goes + * bevelSize: // how far from text outline is bevel + * } + */ + + function TextGeometry( 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; + + ExtrudeGeometry.call( this, shapes, parameters ); + + this.type = 'TextGeometry'; + + } + + TextGeometry.prototype = Object.create( ExtrudeGeometry.prototype ); + TextGeometry.prototype.constructor = TextGeometry; + + /** + * @author benaadams / https://twitter.com/ben_a_adams + * based on THREE.SphereGeometry + */ + + 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 vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) ); + + var positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + var index = 0, vertices = [], normal = new Vector3(); + + for ( var y = 0; y <= heightSegments; y ++ ) { + + var verticesRow = []; + + var v = y / heightSegments; + + for ( var x = 0; x <= widthSegments; x ++ ) { + + var u = x / widthSegments; + + var px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); + var py = radius * Math.cos( thetaStart + v * thetaLength ); + var pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); + + normal.set( px, py, pz ).normalize(); + + positions.setXYZ( index, px, py, pz ); + normals.setXYZ( index, normal.x, normal.y, normal.z ); + uvs.setXY( index, u, 1 - v ); + + verticesRow.push( index ); + + index ++; + + } + + vertices.push( verticesRow ); + + } + + var indices = []; + + for ( var y = 0; y < heightSegments; y ++ ) { + + for ( var x = 0; x < widthSegments; x ++ ) { + + var v1 = vertices[ y ][ x + 1 ]; + var v2 = vertices[ y ][ x ]; + var v3 = vertices[ y + 1 ][ x ]; + var v4 = vertices[ y + 1 ][ x + 1 ]; + + if ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 ); + if ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 ); + + } + + } + + this.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) ); + this.addAttribute( 'position', positions ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + this.boundingSphere = new Sphere( new Vector3(), radius ); + + } + + SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + SphereBufferGeometry.prototype.constructor = SphereBufferGeometry; + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + 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 ) ); + + } + + SphereGeometry.prototype = Object.create( Geometry.prototype ); + SphereGeometry.prototype.constructor = SphereGeometry; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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; + + // these are used to calculate buffer length + var vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 ); + var indexCount = thetaSegments * phiSegments * 2 * 3; + + // buffers + var indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // some helper variables + var index = 0, indexOffset = 0, 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 + + // values are generate from the inside of the ring to the outside + + for ( j = 0; j <= phiSegments; j ++ ) { + + for ( i = 0; i <= thetaSegments; i ++ ) { + + segment = thetaStart + i / thetaSegments * thetaLength; + + // vertex + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normals.setXYZ( index, 0, 0, 1 ); + + // uv + uv.x = ( vertex.x / outerRadius + 1 ) / 2; + uv.y = ( vertex.y / outerRadius + 1 ) / 2; + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index++; + + } + + // increase the radius for next row of vertices + radius += radiusStep; + + } + + // generate indices + + for ( j = 0; j < phiSegments; j ++ ) { + + var thetaSegmentLevel = j * ( thetaSegments + 1 ); + + for ( i = 0; i < thetaSegments; i ++ ) { + + segment = i + thetaSegmentLevel; + + // indices + var a = segment; + var b = segment + thetaSegments + 1; + var c = segment + thetaSegments + 2; + var d = segment + 1; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + + // face two + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + } + + RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + RingBufferGeometry.prototype.constructor = RingBufferGeometry; + + /** + * @author Kaleb Murphy + */ + + 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 ) ); + + } + + RingGeometry.prototype = Object.create( Geometry.prototype ); + RingGeometry.prototype.constructor = RingGeometry; + + /** + * @author mrdoob / http://mrdoob.com/ + * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as + */ + + 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 ) ); + + } + + PlaneGeometry.prototype = Object.create( Geometry.prototype ); + PlaneGeometry.prototype.constructor = PlaneGeometry; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + // points - to create a closed torus, one must use a set of points + // like so: [ a, b, c, d, a ], see first is the same as last. + // segments - the number of circumference segments to create + // phiStart - the starting radian + // phiLength - the radian (0 to 2PI) range of the lathed section + // 2PI is a closed lathe, less than 2PI is a portion. + + 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 ); + + // these are used to calculate buffer length + var vertexCount = ( segments + 1 ) * points.length; + var indexCount = segments * points.length * 2 * 3; + + // buffers + var indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + var index = 0, indexOffset = 0, 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.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // uv + uv.x = i / segments; + uv.y = j / ( points.length - 1 ); + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + } + + // generate indices + + for ( i = 0; i < segments; i ++ ) { + + for ( j = 0; j < ( points.length - 1 ); j ++ ) { + + base = j + i * points.length; + + // indices + var a = base; + var b = base + points.length; + var c = base + points.length + 1; + var d = base + 1; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + // face two + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'uv', uvs ); + + // 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; + + } // next row + + } + + } + + LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; + + /** + * @author astrodud / http://astrodud.isgreat.org/ + * @author zz85 / https://github.com/zz85 + * @author bhouston / http://clara.io + */ + + // points - to create a closed torus, one must use a set of points + // like so: [ a, b, c, d, a ], see first is the same as last. + // segments - the number of circumference segments to create + // phiStart - the starting radian + // phiLength - the radian (0 to 2PI) range of the lathed section + // 2PI is a closed lathe, less than 2PI is a portion. + + 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; + + /** + * @author jonobr1 / http://jonobr1.com + * + * Creates a one-sided polygonal geometry from a path shape. Similar to + * ExtrudeGeometry. + * + * parameters = { + * + * curveSegments: , // number of points on the curves. NOT USED AT THE MOMENT. + * + * material: // material index for front and back faces + * uvGenerator: // object that provides UV generator functions + * + * } + **/ + + function ShapeGeometry( shapes, options ) { + + Geometry.call( this ); + + this.type = 'ShapeGeometry'; + + if ( Array.isArray( shapes ) === false ) shapes = [ shapes ]; + + this.addShapeList( shapes, options ); + + this.computeFaceNormals(); + + } + + ShapeGeometry.prototype = Object.create( Geometry.prototype ); + ShapeGeometry.prototype.constructor = ShapeGeometry; + + /** + * Add an array of shapes to THREE.ShapeGeometry. + */ + ShapeGeometry.prototype.addShapeList = function ( shapes, options ) { + + for ( var i = 0, l = shapes.length; i < l; i ++ ) { + + this.addShape( shapes[ i ], options ); + + } + + return this; + + }; + + /** + * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry. + */ + ShapeGeometry.prototype.addShape = function ( shape, options ) { + + if ( options === undefined ) options = {}; + var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; + + var material = options.material; + var uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator; + + // + + var i, l, hole; + + var shapesOffset = this.vertices.length; + 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 ( i = 0, l = holes.length; i < l; i ++ ) { + + hole = holes[ i ]; + + if ( ShapeUtils.isClockWise( hole ) ) { + + holes[ i ] = hole.reverse(); + + } + + } + + reverse = false; + + } + + var faces = ShapeUtils.triangulateShape( vertices, holes ); + + // Vertices + + for ( i = 0, l = holes.length; i < l; i ++ ) { + + hole = holes[ i ]; + vertices = vertices.concat( hole ); + + } + + // + + var vert, vlen = vertices.length; + var face, flen = faces.length; + + for ( i = 0; i < vlen; i ++ ) { + + vert = vertices[ i ]; + + this.vertices.push( new Vector3( vert.x, vert.y, 0 ) ); + + } + + for ( i = 0; i < flen; i ++ ) { + + face = faces[ i ]; + + var a = face[ 0 ] + shapesOffset; + var b = face[ 1 ] + shapesOffset; + var c = face[ 2 ] + shapesOffset; + + this.faces.push( new Face3( a, b, c, null, null, material ) ); + this.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) ); + + } + + }; + + /** + * @author WestLangley / http://github.com/WestLangley + */ + + function EdgesGeometry( geometry, thresholdAngle ) { + + BufferGeometry.call( this ); + + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; + + var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); + + var edge = [ 0, 0 ], hash = {}; + + function sortFunction( a, b ) { + + return a - b; + + } + + var keys = [ 'a', 'b', 'c' ]; + + var geometry2; + + if ( (geometry && geometry.isBufferGeometry) ) { + + geometry2 = new Geometry(); + geometry2.fromBufferGeometry( geometry ); + + } else { + + geometry2 = geometry.clone(); + + } + + geometry2.mergeVertices(); + geometry2.computeFaceNormals(); + + var vertices = geometry2.vertices; + var faces = geometry2.faces; + + for ( var i = 0, l = faces.length; i < l; i ++ ) { + + var face = faces[ i ]; + + for ( var j = 0; j < 3; j ++ ) { + + edge[ 0 ] = face[ keys[ j ] ]; + edge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ]; + edge.sort( sortFunction ); + + var key = edge.toString(); + + if ( hash[ key ] === undefined ) { + + hash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined }; + + } else { + + hash[ key ].face2 = i; + + } + + } + + } + + var coords = []; + + for ( var key in hash ) { + + var h = hash[ key ]; + + if ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) { + + var vertex = vertices[ h.vert1 ]; + coords.push( vertex.x ); + coords.push( vertex.y ); + coords.push( vertex.z ); + + vertex = vertices[ h.vert2 ]; + coords.push( vertex.x ); + coords.push( vertex.y ); + coords.push( vertex.z ); + + } + + } + + this.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) ); + + } + + EdgesGeometry.prototype = Object.create( BufferGeometry.prototype ); + EdgesGeometry.prototype.constructor = EdgesGeometry; + + /** + * @author Mugen87 / https://github.com/Mugen87 + */ + + 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; + + // used to calculate buffer length + + var nbCap = 0; + + if ( openEnded === false ) { + + if ( radiusTop > 0 ) nbCap ++; + if ( radiusBottom > 0 ) nbCap ++; + + } + + var vertexCount = calculateVertexCount(); + var indexCount = calculateIndexCount(); + + // buffers + + var indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 ); + var vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + + var index = 0, + indexOffset = 0, + indexArray = [], + halfHeight = height / 2; + + // group variables + 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', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + // helper functions + + function calculateVertexCount() { + + var count = ( radialSegments + 1 ) * ( heightSegments + 1 ); + + if ( openEnded === false ) { + + count += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap ); + + } + + return count; + + } + + function calculateIndexCount() { + + var count = radialSegments * heightSegments * 2 * 3; + + if ( openEnded === false ) { + + count += radialSegments * nbCap * 3; + + } + + return count; + + } + + 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.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normal.set( sinTheta, slope, cosTheta ).normalize(); + normals.setXYZ( index, normal.x, normal.y, normal.z ); + + // uv + uvs.setXY( index, u, 1 - v ); + + // save index of vertex in respective row + indexRow.push( index ); + + // increase index + 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 i1 = indexArray[ y ][ x ]; + var i2 = indexArray[ y + 1 ][ x ]; + var i3 = indexArray[ y + 1 ][ x + 1 ]; + var i4 = indexArray[ y ][ x + 1 ]; + + // face one + indices.setX( indexOffset, i1 ); indexOffset ++; + indices.setX( indexOffset, i2 ); indexOffset ++; + indices.setX( indexOffset, i4 ); indexOffset ++; + + // face two + indices.setX( indexOffset, i2 ); indexOffset ++; + indices.setX( indexOffset, i3 ); indexOffset ++; + indices.setX( indexOffset, i4 ); indexOffset ++; + + // update counters + 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.setXYZ( index, 0, halfHeight * sign, 0 ); + + // normal + normals.setXYZ( index, 0, sign, 0 ); + + // uv + uv.x = 0.5; + uv.y = 0.5; + + uvs.setXY( index, uv.x, uv.y ); + + // 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.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normals.setXYZ( index, 0, sign, 0 ); + + // uv + uv.x = ( cosTheta * 0.5 ) + 0.5; + uv.y = ( sinTheta * 0.5 * sign ) + 0.5; + uvs.setXY( index, 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.setX( indexOffset, i ); indexOffset ++; + indices.setX( indexOffset, i + 1 ); indexOffset ++; + indices.setX( indexOffset, c ); indexOffset ++; + + } else { + + // face bottom + indices.setX( indexOffset, i + 1 ); indexOffset ++; + indices.setX( indexOffset, i ); indexOffset ++; + indices.setX( indexOffset, c ); indexOffset ++; + + } + + // update counters + 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 mrdoob / http://mrdoob.com/ + */ + + 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; + + /** + * @author abelnation / http://github.com/abelnation + */ + + 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; + + /** + * @author: abelnation / http://github.com/abelnation + */ + + 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 + */ + + 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; + + var vertices = segments + 2; + + var positions = new Float32Array( vertices * 3 ); + var normals = new Float32Array( vertices * 3 ); + var uvs = new Float32Array( vertices * 2 ); + + // center data is already zero, but need to set a few extras + normals[ 2 ] = 1.0; + uvs[ 0 ] = 0.5; + uvs[ 1 ] = 0.5; + + for ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) { + + var segment = thetaStart + s / segments * thetaLength; + + positions[ i ] = radius * Math.cos( segment ); + positions[ i + 1 ] = radius * Math.sin( segment ); + + normals[ i + 2 ] = 1; // normal z + + uvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2; + uvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2; + + } + + var indices = []; + + for ( var i = 1; i <= segments; i ++ ) { + + indices.push( i, i + 1, 0 ); + + } + + this.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) ); + this.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) ); + + this.boundingSphere = new Sphere( new Vector3(), radius ); + + } + + CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; + + /** + * @author hughes + */ + + 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 ) ); + + } + + CircleGeometry.prototype = Object.create( Geometry.prototype ); + CircleGeometry.prototype.constructor = CircleGeometry; + + /** + * @author mrdoob / http://mrdoob.com/ + * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as + */ + + 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; + + + + 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, + SphereBufferGeometry: SphereBufferGeometry, + SphereGeometry: SphereGeometry, + RingGeometry: RingGeometry, + RingBufferGeometry: RingBufferGeometry, + PlaneBufferGeometry: PlaneBufferGeometry, + PlaneGeometry: PlaneGeometry, + LatheGeometry: LatheGeometry, + LatheBufferGeometry: LatheBufferGeometry, + ShapeGeometry: ShapeGeometry, + ExtrudeGeometry: ExtrudeGeometry, + EdgesGeometry: EdgesGeometry, + ConeGeometry: ConeGeometry, + ConeBufferGeometry: ConeBufferGeometry, + CylinderGeometry: CylinderGeometry, + CylinderBufferGeometry: CylinderBufferGeometry, + CircleBufferGeometry: CircleBufferGeometry, + CircleGeometry: CircleGeometry, + BoxBufferGeometry: BoxBufferGeometry, + BoxGeometry: BoxGeometry + }); + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function ShadowMaterial() { + + 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; + } + } + } ); + + } + + 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 mrdoob / http://mrdoob.com/ + */ + + function MultiMaterial( materials ) { + + this.uuid = _Math.generateUUID(); + + this.type = 'MultiMaterial'; + + this.materials = materials instanceof Array ? materials : []; + + this.visible = true; + + } + + MultiMaterial.prototype = { + + constructor: MultiMaterial, + + isMultiMaterial: true, + + toJSON: function ( meta ) { + + var output = { + metadata: { + version: 4.2, + type: 'material', + generator: 'MaterialExporter' + }, + uuid: this.uuid, + type: this.type, + materials: [] + }; + + var materials = this.materials; + + for ( var i = 0, l = materials.length; i < l; i ++ ) { + + var material = materials[ i ].toJSON( meta ); + delete material.metadata; + + output.materials.push( material ); + + } + + output.visible = this.visible; + + return output; + + }, + + clone: function () { + + var material = new this.constructor(); + + for ( var i = 0; i < this.materials.length; i ++ ) { + + material.materials.push( this.materials[ i ].clone() ); + + } + + material.visible = this.visible; + + return material; + + } + + }; + + /** + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * color: , + * roughness: , + * metalness: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * roughnessMap: new THREE.Texture( ), + * + * metalnessMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * envMapIntensity: + * + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ + + 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: + * } + */ + + 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: , + * specular: , + * shininess: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ + + 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 mrdoob / http://mrdoob.com/ + * + * parameters = { + * opacity: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ + + function MeshNormalMaterial( parameters ) { + + Material.call( this, parameters ); + + this.type = 'MeshNormalMaterial'; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.fog = false; + this.lights = false; + this.morphTargets = 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.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + + return this; + + }; + + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ + + 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: , + * opacity: , + * + * linewidth: , + * + * scale: , + * dashSize: , + * gapSize: + * } + */ + + 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, + MultiMaterial: MultiMaterial, + MeshPhysicalMaterial: MeshPhysicalMaterial, + MeshStandardMaterial: MeshStandardMaterial, + MeshPhongMaterial: MeshPhongMaterial, + 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 XHRLoader( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + } + + Object.assign( XHRLoader.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.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.XHRLoader: HTTP Status 0 received.' ); + + if ( onLoad ) onLoad( response ); + + scope.manager.itemEnd( url ); + + } else { + + if ( onError ) onError( event ); + + 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.itemError( url ); + + }, false ); + + if ( this.responseType !== undefined ) request.responseType = this.responseType; + if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; + + if ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' ); + + 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; + + } + + } ); + + /** + * @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 XHRLoader( 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, ...) + */ + + var DataTextureLoader = BinaryTextureLoader; + function BinaryTextureLoader( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + // override in sub classes + this._parser = null; + + } + + Object.assign( BinaryTextureLoader.prototype, { + + load: function ( url, onLoad, onProgress, onError ) { + + var scope = this; + + var texture = new DataTexture(); + + var loader = new XHRLoader( 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 ) { + + var scope = this; + + var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' ); + image.onload = function () { + + image.onload = null; + + URL.revokeObjectURL( image.src ); + + if ( onLoad ) onLoad( image ); + + scope.manager.itemEnd( url ); + + }; + image.onerror = onError; + + if ( url.indexOf( 'data:' ) === 0 ) { + + image.src = url; + + } else { + + var loader = new XHRLoader(); + loader.setPath( this.path ); + loader.setResponseType( 'blob' ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( blob ) { + + image.src = URL.createObjectURL( blob ); + + }, onProgress, onError ); + + } + + scope.manager.itemStart( url ); + + return image; + + }, + + setCrossOrigin: function ( value ) { + + this.crossOrigin = value; + return this; + + }, + + setWithCredentials: function ( value ) { + + this.withCredentials = 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 texture = new Texture(); + + var loader = new ImageLoader( this.manager ); + loader.setCrossOrigin( this.crossOrigin ); + loader.setWithCredentials( this.withCredentials ); + loader.setPath( this.path ); + loader.load( url, function ( image ) { + + // 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.image = image; + texture.needsUpdate = true; + + if ( onLoad !== undefined ) { + + onLoad( texture ); + + } + + }, onProgress, onError ); + + return texture; + + }, + + setCrossOrigin: function ( value ) { + + this.crossOrigin = value; + return this; + + }, + + setWithCredentials: function ( value ) { + + this.withCredentials = 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 fov = _Math.RAD2DEG * 2 * light.angle; + var aspect = this.mapSize.width / this.mapSize.height; + var far = light.distance || 500; + + var camera = this.camera; + + 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( light ) { + + 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 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 ) ) { + + return new array.constructor( array.subarray( from, to ) ); + + } + + 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; + + } + + Interpolant.prototype = { + + constructor: Interpolant, + + 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 + + } + + }; + + Object.assign( Interpolant.prototype, { + + beforeStart_: //( 0, t, t0 ), returns this.resultBuffer + Interpolant.prototype.copySampleValue_, + + afterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer + 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(); + + } + + AnimationClip.prototype = { + + constructor: AnimationClip, + + 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; + + } + + }; + + // Static methods: + + 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; + + } + + } ); + + /** + * @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 XHRLoader( scope.manager ); + loader.load( url, function ( text ) { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + }, 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.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; + + // MultiMaterial + + if ( json.materials !== undefined ) { + + for ( var i = 0, l = json.materials.length; i < l; i ++ ) { + + material.materials.push( this.parse( json.materials[ i ] ) ); + + } + + } + + 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 XHRLoader( scope.manager ); + loader.load( url, function ( text ) { + + onLoad( scope.parse( JSON.parse( text ) ) ); + + }, onProgress, onError ); + + }, + + parse: function ( json ) { + + var geometry = new BufferGeometry(); + + var index = json.data.index; + + var TYPED_ARRAYS = { + 'Int8Array': Int8Array, + 'Uint8Array': Uint8Array, + 'Uint8ClampedArray': Uint8ClampedArray, + 'Int16Array': Int16Array, + 'Uint16Array': Uint16Array, + 'Int32Array': Int32Array, + 'Uint32Array': Uint32Array, + 'Float32Array': Float32Array, + 'Float64Array': Float64Array + }; + + 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; + + } + + } ); + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + function Loader() { + + this.onLoadStart = function () {}; + this.onLoadProgress = function () {}; + this.onLoadComplete = function () {}; + + } + + Loader.prototype = { + + constructor: Loader, + + 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 color, textureLoader, materialLoader; + + return function createMaterial( m, texturePath, crossOrigin ) { + + if ( color === undefined ) color = new Color(); + if ( textureLoader === undefined ) textureLoader = new TextureLoader(); + if ( materialLoader === undefined ) materialLoader = new MaterialLoader(); + + // 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 ); + + }; + + } )() + + }; + + 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; + + } + + }; + + /** + * @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 XHRLoader( this.manager ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { + + var json = JSON.parse( text ); + 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 ( json, texturePath ) { + + var geometry = new Geometry(), + scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0; + + parseModel( scale ); + + parseSkin(); + parseMorphing( scale ); + parseAnimations(); + + geometry.computeFaceNormals(); + geometry.computeBoundingSphere(); + + function parseModel( scale ) { + + 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, + + 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() { + + 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( 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() { + + 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; + + } + + 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 XHRLoader( scope.manager ); + loader.load( url, function ( text ) { + + scope.parse( JSON.parse( text ), 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.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 material = loader.parse( json[ i ] ); + materials[ material.uuid ] = material; + + } + + } + + 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.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, TextureMapping ); + + 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 ], TextureWrapping ); + texture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping ); + + } + + if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter ); + if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter ); + 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 ( 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 '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 '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 '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; + + }; + + }() + + } ); + + /** + * @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 classes subclasses THREE.Curve: + * + * -- 2d classes -- + * THREE.LineCurve + * THREE.QuadraticBezierCurve + * THREE.CubicBezierCurve + * THREE.SplineCurve + * THREE.ArcCurve + * THREE.EllipseCurve + * + * -- 3d classes -- + * THREE.LineCurve3 + * THREE.QuadraticBezierCurve3 + * THREE.CubicBezierCurve3 + * THREE.SplineCurve3 + * + * A series of curves can be represented as a THREE.CurvePath + * + **/ + + /************************************************************** + * Abstract Curve base class + **************************************************************/ + + function Curve() {} + + Curve.prototype = { + + constructor: Curve, + + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] + + getPoint: function ( t ) { + + console.warn( "THREE.Curve: Warning, 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 ) 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 ) 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 ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200; + + if ( this.cacheArcLengths + && ( this.cacheArcLengths.length === divisions + 1 ) + && ! this.needsUpdate ) { + + //console.log( "cached", this.cacheArcLengths ); + 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 ]; + + } + + //var time = Date.now(); + + // 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; + + //console.log('b' , i, low, high, Date.now()- time); + + if ( arcLengths[ i ] === targetArcLength ) { + + var t = i / ( il - 1 ); + return t; + + } + + // 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 + }; + + } + + }; + + // TODO: Transformation for Curves? + + /************************************************************** + * 3D Curves + **************************************************************/ + + // A Factory method for creating new curve subclasses + + Curve.create = function ( constructor, getPointFunc ) { + + constructor.prototype = Object.create( Curve.prototype ); + constructor.prototype.constructor = constructor; + constructor.prototype.getPoint = getPointFunc; + + return constructor; + + }; + + /************************************************************** + * Line + **************************************************************/ + + function LineCurve( v1, v2 ) { + + 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() { + + 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 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; + + } + + } ); + + /************************************************************** + * Ellipse curve + **************************************************************/ + + function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { + + 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 ); + + }; + + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + */ + + var CurveUtils = { + + tangentQuadraticBezier: function ( t, p0, p1, p2 ) { + + return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 ); + + }, + + // Puay Bing, thanks for helping with this derivative! + + tangentCubicBezier: function ( t, p0, p1, p2, p3 ) { + + return - 3 * p0 * ( 1 - t ) * ( 1 - t ) + + 3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) + + 6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 + + 3 * t * t * p3; + + }, + + tangentSpline: function ( t, p0, p1, p2, p3 ) { + + // To check if my formulas are correct + + var h00 = 6 * t * t - 6 * t; // derived from 2t^3 − 3t^2 + 1 + var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t + var h01 = - 6 * t * t + 6 * t; // − 2t3 + 3t2 + var h11 = 3 * t * t - 2 * t; // t3 − t2 + + return h00 + h10 + h01 + h11; + + }, + + // Catmull-Rom + + interpolate: function( p0, p1, p2, p3, t ) { + + 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; + + } + + }; + + /************************************************************** + * Spline curve + **************************************************************/ + + function SplineCurve( points /* array of Vector2 */ ) { + + 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 ]; + + var interpolate = CurveUtils.interpolate; + + return new Vector2( + interpolate( point0.x, point1.x, point2.x, point3.x, weight ), + interpolate( point0.y, point1.y, point2.y, point3.y, weight ) + ); + + }; + + /************************************************************** + * Cubic Bezier curve + **************************************************************/ + + function CubicBezierCurve( v0, v1, v2, v3 ) { + + 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 b3 = ShapeUtils.b3; + + return new Vector2( + b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ), + b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ) + ); + + }; + + CubicBezierCurve.prototype.getTangent = function( t ) { + + var tangentCubicBezier = CurveUtils.tangentCubicBezier; + + return new Vector2( + tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ), + tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ) + ).normalize(); + + }; + + /************************************************************** + * Quadratic Bezier curve + **************************************************************/ + + + function QuadraticBezierCurve( v0, v1, v2 ) { + + 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 b2 = ShapeUtils.b2; + + return new Vector2( + b2( t, this.v0.x, this.v1.x, this.v2.x ), + b2( t, this.v0.y, this.v1.y, this.v2.y ) + ); + + }; + + + QuadraticBezierCurve.prototype.getTangent = function( t ) { + + var tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier; + + return new Vector2( + tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ), + tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y ) + ).normalize(); + + }; + + 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 + * 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 + * 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; + + + // minimal class for proxing functions to Path. Replaces old "extractSubpaths()" + function ShapePath() { + this.subPaths = []; + this.currentPath = null; + } + + 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 offset = 0; + + var paths = []; + + for ( var i = 0; i < chars.length; i ++ ) { + + var ret = createPath( chars[ i ], scale, offset ); + offset += ret.offset; + + paths.push( ret.path ); + + } + + return paths; + + } + + function createPath( c, scale, offset ) { + + var glyph = data.glyphs[ c ] || data.glyphs[ '?' ]; + + if ( ! glyph ) return; + + var path = new ShapePath(); + + var pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3; + 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 + offset; + y = outline[ i ++ ] * scale; + + path.moveTo( x, y ); + + break; + + case 'l': // lineTo + + x = outline[ i ++ ] * scale + offset; + y = outline[ i ++ ] * scale; + + path.lineTo( x, y ); + + break; + + case 'q': // quadraticCurveTo + + cpx = outline[ i ++ ] * scale + offset; + cpy = outline[ i ++ ] * scale; + cpx1 = outline[ i ++ ] * scale + offset; + cpy1 = outline[ i ++ ] * scale; + + path.quadraticCurveTo( cpx1, cpy1, cpx, cpy ); + + laste = pts[ pts.length - 1 ]; + + if ( laste ) { + + cpx0 = laste.x; + cpy0 = laste.y; + + for ( var i2 = 1; i2 <= divisions; i2 ++ ) { + + var t = i2 / divisions; + b2( t, cpx0, cpx1, cpx ); + b2( t, cpy0, cpy1, cpy ); + + } + + } + + break; + + case 'b': // bezierCurveTo + + cpx = outline[ i ++ ] * scale + offset; + cpy = outline[ i ++ ] * scale; + cpx1 = outline[ i ++ ] * scale + offset; + cpy1 = outline[ i ++ ] * scale; + cpx2 = outline[ i ++ ] * scale + offset; + cpy2 = outline[ i ++ ] * scale; + + path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy ); + + laste = pts[ pts.length - 1 ]; + + if ( laste ) { + + cpx0 = laste.x; + cpy0 = laste.y; + + for ( var i2 = 1; i2 <= divisions; i2 ++ ) { + + var t = i2 / divisions; + b3( t, cpx0, cpx1, cpx2, cpx ); + b3( t, cpy0, cpy1, cpy2, cpy ); + + } + + } + + break; + + } + + } + + } + + return { offset: 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 XHRLoader( 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; + + function getAudioContext() { + + if ( context === undefined ) { + + context = new ( window.AudioContext || window.webkitAudioContext )(); + + } + + return context; + + } + + /** + * @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 XHRLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); + loader.load( url, function ( buffer ) { + + var context = getAudioContext(); + + 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; + + 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; + + 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(); + var 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.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 AudioListener() { + + Object3D.call( this ); + + this.type = 'AudioListener'; + + this.context = getAudioContext(); + + 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 ); + + 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.source = this.context.createBufferSource(); + this.source.onended = this.onEnded.bind( this ); + + this.gain = this.context.createGain(); + this.gain.connect( listener.getInput() ); + + this.autoplay = 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.source.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.source.buffer; + source.loop = this.source.loop; + source.onended = this.source.onended; + source.start( 0, this.startTime ); + source.playbackRate.value = this.playbackRate; + + 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.value = this.playbackRate; + + } + + 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.source.loop; + + }, + + setLoop: function ( value ) { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + this.source.loop = value; + + }, + + 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; + + } + + PropertyMixer.prototype = { + + constructor: PropertyMixer, + + // accumulate data in the 'incoming' region into 'accu' + 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' 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, stride ) { + + 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 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; + + } + + PropertyBinding.prototype = { + + constructor: PropertyBinding, + + 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 ( nodeProperty.length !== undefined ) { + + 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; + + } + + }; + + Object.assign( PropertyBinding.prototype, { // prototype, continued + + // these are used to "bind" a nonexistent property + _getValue_unavailable: function() {}, + _setValue_unavailable: function() {}, + + // initial state of these methods that calls 'bind' + _getValue_unbound: PropertyBinding.prototype.getValue, + _setValue_unbound: PropertyBinding.prototype.setValue, + + 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; + + } + + ] + + ] + + } ); + + PropertyBinding.Composite = + function( targetGroup, path, optionalParsedPath ) { + + var parsedPath = optionalParsedPath || + PropertyBinding.parseTrackName( path ); + + this._targetGroup = targetGroup; + this._bindings = targetGroup.subscribe_( path, parsedPath ); + + }; + + PropertyBinding.Composite.prototype = { + + constructor: PropertyBinding.Composite, + + 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(); + + } + + } + + }; + + PropertyBinding.create = function( root, path, parsedPath ) { + + if ( ! ( (root && root.isAnimationObjectGroup) ) ) { + + return new PropertyBinding( root, path, parsedPath ); + + } else { + + return new PropertyBinding.Composite( root, path, parsedPath ); + + } + + }; + + PropertyBinding.parseTrackName = function( trackName ) { + + // matches strings in the form of: + // nodeName.property + // nodeName.property[accessor] + // nodeName.material.property[accessor] + // uuid.property[accessor] + // uuid.objectName[objectIndex].propertyName[propertyIndex] + // parentName/nodeName.property + // parentName/parentName/nodeName.property[index] + // .bone[Armature.DEF_cog].position + // scene:helium_balloon_model:helium_balloon_model.position + // created and tested via https://regex101.com/#javascript + + var re = /^((?:\w+[\/:])*)(\w+)?(?:\.(\w+)(?:\[(.+)\])?)?\.(\w+)(?:\[(.+)\])?$/; + var matches = re.exec( trackName ); + + if ( ! matches ) { + + throw new Error( "cannot parse trackName at all: " + trackName ); + + } + + var results = { + // directoryName: matches[ 1 ], // (tschw) currently unused + nodeName: matches[ 2 ], // allowed to be null, specified root node. + objectName: matches[ 3 ], + objectIndex: matches[ 4 ], + propertyName: matches[ 5 ], + propertyIndex: matches[ 6 ] // allowed to be null, specifies that the whole property is set. + }; + + if ( results.propertyName === null || results.propertyName.length === 0 ) { + + throw new Error( "can not parse propertyName from trackName: " + trackName ); + + } + + return results; + + }; + + PropertyBinding.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; + + }; + + /** + * + * 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; } + + }; + + } + + AnimationObjectGroup.prototype = { + + constructor: AnimationObjectGroup, + + 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 ]; + + 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 ) { + + var 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; // false -> zero effective time scale + this.enabled = true; // true -> 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 + + } + + AnimationAction.prototype = { + + constructor: AnimationAction, + + // 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 weight 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 + + 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, { + + // 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 ]; + + if ( action.enabled ) { + + 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 ); + + } + + } + + } ); + + // Implementation details: + + Object.assign( AnimationMixer.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 = ( actions._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 ) + + } ); + + /** + * @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; + + } + + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ + + function InstancedBufferGeometry() { + + BufferGeometry.call( this ); + + this.type = 'InstancedBufferGeometry'; + this.maxInstancedCount = undefined; + + } + + InstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + InstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry; + + InstancedBufferGeometry.prototype.isInstancedBufferGeometry = true; + + InstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) { + + this.groups.push( { + + start: start, + count: count, + materialIndex: materialIndex + + } ); + + }; + + InstancedBufferGeometry.prototype.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; + + } + + + InterleavedBufferAttribute.prototype = { + + constructor: InterleavedBufferAttribute, + + isInterleavedBufferAttribute: true, + + get count() { + + return this.data.count; + + }, + + get array() { + + return this.data.array; + + }, + + 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.version = 0; + + } + + InterleavedBuffer.prototype = { + + constructor: InterleavedBuffer, + + isInterleavedBuffer: true, + + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + + }, + + 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 ); + + } + + }; + + /** + * @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.create( InterleavedBuffer.prototype ); + InstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer; + + InstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true; + + InstancedInterleavedBuffer.prototype.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.create( BufferAttribute.prototype ); + InstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute; + + InstancedBufferAttribute.prototype.isInstancedBufferAttribute = true; + + InstancedBufferAttribute.prototype.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 ); + + } + + } + + } + + // + + Raycaster.prototype = { + + constructor: Raycaster, + + 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; + + } + + Clock.prototype = { + + constructor: Clock, + + start: function () { + + this.startTime = ( performance || Date ).now(); + + 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(); + + } + + if ( this.running ) { + + var newTime = ( performance || Date ).now(); + + diff = ( newTime - this.oldTime ) / 1000; + this.oldTime = newTime; + + this.elapsedTime += diff; + + } + + return diff; + + } + + }; + + /** + * Spline from Tween.js, slightly optimized (and trashed) + * http://sole.github.com/tween.js/examples/05_spline.html + * + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ + + function Spline( points ) { + + this.points = points; + + var c = [], v3 = { x: 0, y: 0, z: 0 }, + point, intPoint, weight, w2, w3, + pa, pb, pc, pd; + + this.initFromArray = function ( a ) { + + this.points = []; + + for ( var i = 0; i < a.length; i ++ ) { + + this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] }; + + } + + }; + + this.getPoint = function ( k ) { + + point = ( this.points.length - 1 ) * k; + intPoint = Math.floor( point ); + weight = point - intPoint; + + c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1; + c[ 1 ] = intPoint; + c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1; + c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2; + + pa = this.points[ c[ 0 ] ]; + pb = this.points[ c[ 1 ] ]; + pc = this.points[ c[ 2 ] ]; + pd = this.points[ c[ 3 ] ]; + + w2 = weight * weight; + w3 = weight * w2; + + v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 ); + v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 ); + v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 ); + + return v3; + + }; + + this.getControlPointsArray = function () { + + var i, p, l = this.points.length, + coords = []; + + for ( i = 0; i < l; i ++ ) { + + p = this.points[ i ]; + coords[ i ] = [ p.x, p.y, p.z ]; + + } + + return coords; + + }; + + // approximate length by summing linear segments + + this.getLength = function ( nSubDivisions ) { + + var i, index, nSamples, position, + point = 0, intPoint = 0, oldIntPoint = 0, + oldPosition = new Vector3(), + tmpVec = new Vector3(), + chunkLengths = [], + totalLength = 0; + + // first point has 0 length + + chunkLengths[ 0 ] = 0; + + if ( ! nSubDivisions ) nSubDivisions = 100; + + nSamples = this.points.length * nSubDivisions; + + oldPosition.copy( this.points[ 0 ] ); + + for ( i = 1; i < nSamples; i ++ ) { + + index = i / nSamples; + + position = this.getPoint( index ); + tmpVec.copy( position ); + + totalLength += tmpVec.distanceTo( oldPosition ); + + oldPosition.copy( position ); + + point = ( this.points.length - 1 ) * index; + intPoint = Math.floor( point ); + + if ( intPoint !== oldIntPoint ) { + + chunkLengths[ intPoint ] = totalLength; + oldIntPoint = intPoint; + + } + + } + + // last point ends with total length + + chunkLengths[ chunkLengths.length ] = totalLength; + + return { chunks: chunkLengths, total: totalLength }; + + }; + + this.reparametrizeByArcLength = function ( samplingCoef ) { + + var i, j, + index, indexCurrent, indexNext, + realDistance, + sampling, position, + newpoints = [], + tmpVec = new Vector3(), + sl = this.getLength(); + + newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() ); + + for ( i = 1; i < this.points.length; i ++ ) { + + //tmpVec.copy( this.points[ i - 1 ] ); + //linearDistance = tmpVec.distanceTo( this.points[ i ] ); + + realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ]; + + sampling = Math.ceil( samplingCoef * realDistance / sl.total ); + + indexCurrent = ( i - 1 ) / ( this.points.length - 1 ); + indexNext = i / ( this.points.length - 1 ); + + for ( j = 1; j < sampling - 1; j ++ ) { + + index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent ); + + position = this.getPoint( index ); + newpoints.push( tmpVec.copy( position ).clone() ); + + } + + newpoints.push( tmpVec.copy( this.points[ i ] ).clone() ); + + } + + this.points = newpoints; + + }; + + // Catmull-Rom + + function interpolate( p0, p1, p2, p3, t, t2, t3 ) { + + var v0 = ( p2 - p0 ) * 0.5, + v1 = ( p3 - p1 ) * 0.5; + + return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1; + + } + + } + + /** + * @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; + + } + + Spherical.prototype = { + + constructor: Spherical, + + 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 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 Float32Attribute( 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; + + return this; + + }; + + }() ); + + /** + * @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 Float32Attribute( 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 ).multiplyScalar( this.light.intensity ); + + }; + + }(); + + /** + * @author Sean Griffin / http://twitter.com/sgrif + * @author Michael Guerrero / http://realitymeltdown.com + * @author mrdoob / http://mrdoob.com/ + * @author ikerr / http://verold.com + */ + + function SkeletonHelper( object ) { + + this.bones = this.getBoneList( object ); + + var geometry = new Geometry(); + + for ( var i = 0; i < this.bones.length; i ++ ) { + + var bone = this.bones[ i ]; + + if ( (bone.parent && bone.parent.isBone) ) { + + geometry.vertices.push( new Vector3() ); + geometry.vertices.push( new Vector3() ); + geometry.colors.push( new Color( 0, 0, 1 ) ); + geometry.colors.push( new Color( 0, 1, 0 ) ); + + } + + } + + geometry.dynamic = true; + + 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 geometry = this.geometry; + + var matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld ); + + var boneMatrix = new Matrix4(); + + var j = 0; + + for ( var i = 0; i < this.bones.length; i ++ ) { + + var bone = this.bones[ i ]; + + if ( (bone.parent && bone.parent.isBone) ) { + + boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld ); + geometry.vertices[ j ].setFromMatrixPosition( boneMatrix ); + + boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld ); + geometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix ); + + j += 2; + + } + + } + + geometry.verticesNeedUpdate = true; + + geometry.computeBoundingSphere(); + + }; + + /** + * @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 ).multiplyScalar( this.light.intensity ); + + 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 ).multiplyScalar( this.light.intensity ); + + /* + 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 alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ + + function HemisphereLightHelper( light, sphereSize ) { + + Object3D.call( this ); + + this.light = light; + this.light.updateMatrixWorld(); + + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; + + this.colors = [ new Color(), new Color() ]; + + var geometry = new SphereGeometry( sphereSize, 4, 2 ); + geometry.rotateX( - Math.PI / 2 ); + + for ( var i = 0, il = 8; i < il; i ++ ) { + + geometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ]; + + } + + var material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } ); + + this.lightSphere = new Mesh( geometry, material ); + this.add( this.lightSphere ); + + this.update(); + + } + + HemisphereLightHelper.prototype = Object.create( Object3D.prototype ); + HemisphereLightHelper.prototype.constructor = HemisphereLightHelper; + + HemisphereLightHelper.prototype.dispose = function () { + + this.lightSphere.geometry.dispose(); + this.lightSphere.material.dispose(); + + }; + + HemisphereLightHelper.prototype.update = function () { + + var vector = new Vector3(); + + return function update() { + + this.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity ); + this.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity ); + + this.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); + this.lightSphere.geometry.colorsNeedUpdate = true; + + }; + + }(); + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function GridHelper( size, divisions, color1, color2 ) { + + divisions = divisions || 1; + color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); + color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); + + var center = divisions / 2; + var step = ( size * 2 ) / divisions; + var vertices = [], colors = []; + + for ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) { + + vertices.push( - size, 0, k, size, 0, k ); + vertices.push( k, 0, - size, k, 0, size ); + + 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 Float32Attribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) ); + + var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + + LineSegments.call( this, geometry, material ); + + } + + GridHelper.prototype = Object.create( LineSegments.prototype ); + GridHelper.prototype.constructor = GridHelper; + + GridHelper.prototype.setColors = function () { + + console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); + + }; + + /** + * @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 Float32Attribute( 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; + + return this; + + }; + + }() ); + + /** + * @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 Float32Attribute( [ + - 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 Float32Attribute( [ 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 ).multiplyScalar( this.light.intensity ); + + targetLine.lookAt( v3 ); + targetLine.scale.z = v3.length(); + + }; + + }(); + + /** + * @author alteredq / http://alteredqualia.com/ + * + * - 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 Geometry(); + var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); + + var pointMap = {}; + + // colors + + var hexFrustum = 0xffaa00; + var hexCone = 0xff0000; + var hexUp = 0x00aaff; + var hexTarget = 0xffffff; + var hexCross = 0x333333; + + // near + + addLine( "n1", "n2", hexFrustum ); + addLine( "n2", "n4", hexFrustum ); + addLine( "n4", "n3", hexFrustum ); + addLine( "n3", "n1", hexFrustum ); + + // far + + addLine( "f1", "f2", hexFrustum ); + addLine( "f2", "f4", hexFrustum ); + addLine( "f4", "f3", hexFrustum ); + addLine( "f3", "f1", hexFrustum ); + + // sides + + addLine( "n1", "f1", hexFrustum ); + addLine( "n2", "f2", hexFrustum ); + addLine( "n3", "f3", hexFrustum ); + addLine( "n4", "f4", hexFrustum ); + + // cone + + addLine( "p", "n1", hexCone ); + addLine( "p", "n2", hexCone ); + addLine( "p", "n3", hexCone ); + addLine( "p", "n4", hexCone ); + + // up + + addLine( "u1", "u2", hexUp ); + addLine( "u2", "u3", hexUp ); + addLine( "u3", "u1", hexUp ); + + // target + + addLine( "c", "t", hexTarget ); + addLine( "p", "c", hexCross ); + + // cross + + addLine( "cn1", "cn2", hexCross ); + addLine( "cn3", "cn4", hexCross ); + + addLine( "cf1", "cf2", hexCross ); + addLine( "cf3", "cf4", hexCross ); + + function addLine( a, b, hex ) { + + addPoint( a, hex ); + addPoint( b, hex ); + + } + + function addPoint( id, hex ) { + + geometry.vertices.push( new Vector3() ); + geometry.colors.push( new Color( hex ) ); + + if ( pointMap[ id ] === undefined ) { + + pointMap[ id ] = []; + + } + + pointMap[ id ].push( geometry.vertices.length - 1 ); + + } + + 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 ) { + + for ( var i = 0, il = points.length; i < il; i ++ ) { + + geometry.vertices[ points[ i ] ].copy( vector ); + + } + + } + + } + + 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.verticesNeedUpdate = true; + + }; + + }(); + + /** + * @author WestLangley / http://github.com/WestLangley + */ + + // a helper to show the world-axis-aligned bounding box for an object + + function BoundingBoxHelper( object, hex ) { + + var color = ( hex !== undefined ) ? hex : 0x888888; + + this.object = object; + + this.box = new Box3(); + + Mesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) ); + + } + + BoundingBoxHelper.prototype = Object.create( Mesh.prototype ); + BoundingBoxHelper.prototype.constructor = BoundingBoxHelper; + + BoundingBoxHelper.prototype.update = function () { + + this.box.setFromObject( this.object ); + + this.box.getSize( this.scale ); + + this.box.getCenter( this.position ); + + }; + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function BoxHelper( object, color ) { + + 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 } ) ); + + if ( object !== undefined ) { + + this.update( object ); + + } + + } + + BoxHelper.prototype = Object.create( LineSegments.prototype ); + BoxHelper.prototype.constructor = BoxHelper; + + BoxHelper.prototype.update = ( function () { + + var box = new Box3(); + + return function update( object ) { + + if ( (object && object.isBox3) ) { + + box.copy( object ); + + } else { + + box.setFromObject( 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(); + + }; + + } )(); + + /** + * @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 = new BufferGeometry(); + lineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); + + var coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); + coneGeometry.translate( 0, - 0.5, 0 ); + + 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; + + 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 = new Float32Array( [ + 0, 0, 0, size, 0, 0, + 0, 0, 0, 0, size, 0, + 0, 0, 0, 0, 0, size + ] ); + + var colors = new Float32Array( [ + 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 BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new BufferAttribute( 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 + */ + + var CatmullRomCurve3 = ( function() { + + var + tmp = new Vector3(), + px = new CubicPoly(), + py = new CubicPoly(), + pz = new CubicPoly(); + + /* + 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() {} + + /* + * 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. + */ + CubicPoly.prototype.init = function( x0, x1, t0, t1 ) { + + this.c0 = x0; + this.c1 = t0; + this.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; + this.c3 = 2 * x0 - 2 * x1 + t0 + t1; + + }; + + CubicPoly.prototype.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; + + // initCubicPoly + this.init( x1, x2, t1, t2 ); + + }; + + // standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4 + CubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) { + + this.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); + + }; + + CubicPoly.prototype.calc = function( t ) { + + var t2 = t * t; + var t3 = t2 * t; + return this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3; + + }; + + // Subclass Three.js curve + return Curve.create( + + function ( p /* array of Vector3 */ ) { + + this.points = p || []; + this.closed = false; + + }, + + function ( t ) { + + var points = this.points, + point, intPoint, weight, l; + + l = points.length; + + if ( l < 2 ) console.log( 'duh, you need at least 2 points' ); + + point = ( l - ( this.closed ? 0 : 1 ) ) * t; + intPoint = Math.floor( point ); + 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 ); + + } + + var v = new Vector3( + px.calc( weight ), + py.calc( weight ), + pz.calc( weight ) + ); + + return v; + + } + + ); + + } )(); + + /************************************************************** + * Closed Spline 3D curve + **************************************************************/ + + + function ClosedSplineCurve3( points ) { + + console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' ); + + CatmullRomCurve3.call( this, points ); + this.type = 'catmullrom'; + this.closed = true; + + } + + ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); + + /************************************************************** + * Spline 3D curve + **************************************************************/ + + + var SplineCurve3 = Curve.create( + + function ( points /* array of Vector3 */ ) { + + console.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' ); + this.points = ( points === undefined ) ? [] : points; + + }, + + 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 ]; + + var interpolate = CurveUtils.interpolate; + + return new Vector3( + interpolate( point0.x, point1.x, point2.x, point3.x, weight ), + interpolate( point0.y, point1.y, point2.y, point3.y, weight ), + interpolate( point0.z, point1.z, point2.z, point3.z, weight ) + ); + + } + + ); + + /************************************************************** + * Cubic Bezier 3D curve + **************************************************************/ + + var CubicBezierCurve3 = Curve.create( + + function ( v0, v1, v2, v3 ) { + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + + }, + + function ( t ) { + + var b3 = ShapeUtils.b3; + + return new Vector3( + b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ), + b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ), + b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z ) + ); + + } + + ); + + /************************************************************** + * Quadratic Bezier 3D curve + **************************************************************/ + + var QuadraticBezierCurve3 = Curve.create( + + function ( v0, v1, v2 ) { + + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + + }, + + function ( t ) { + + var b2 = ShapeUtils.b2; + + return new Vector3( + b2( t, this.v0.x, this.v1.x, this.v2.x ), + b2( t, this.v0.y, this.v1.y, this.v2.y ), + b2( t, this.v0.z, this.v1.z, this.v2.z ) + ); + + } + + ); + + /************************************************************** + * Line3D + **************************************************************/ + + var LineCurve3 = Curve.create( + + function ( v1, v2 ) { + + this.v1 = v1; + this.v2 = v2; + + }, + + 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; + + } + + ); + + /************************************************************** + * Arc curve + **************************************************************/ + + 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; + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + var SceneUtils = { + + createMultiMaterialObject: function ( geometry, materials ) { + + var group = new Group(); + + for ( var i = 0, l = materials.length; i < l; i ++ ) { + + group.add( new Mesh( geometry, materials[ i ] ) ); + + } + + return group; + + }, + + detach: function ( child, parent, scene ) { + + child.applyMatrix( parent.matrixWorld ); + parent.remove( child ); + scene.add( child ); + + }, + + attach: function ( child, scene, parent ) { + + var matrixWorldInverse = new Matrix4(); + matrixWorldInverse.getInverse( parent.matrixWorld ); + child.applyMatrix( matrixWorldInverse ); + + scene.remove( child ); + parent.add( child ); + + } + + }; + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function Face4 ( a, b, c, d, normal, color, materialIndex ) { + console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); + return new Face3( a, b, c, normal, color, materialIndex ); + } + + var LineStrip = 0; + + var LinePieces = 1; + + function PointCloud ( geometry, material ) { + console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); + return new Points( geometry, material ); + } + + function ParticleSystem ( geometry, material ) { + console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); + return new Points( geometry, material ); + } + + function PointCloudMaterial ( parameters ) { + console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); + } + + function ParticleBasicMaterial ( parameters ) { + console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); + } + + function ParticleSystemMaterial ( parameters ) { + console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); + } + + function Vertex ( x, y, z ) { + console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' ); + return new Vector3( x, y, z ); + } + + // + + function EdgesHelper( object, hex ) { + console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' ); + return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); + } + + function WireframeHelper( object, hex ) { + console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' ); + return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); + } + + // + + 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 ); + } + } ); + + Object.assign( Line3.prototype, { + center: function ( optionalTarget ) { + console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); + return this.getCenter( optionalTarget ); + } + } ); + + Object.assign( Matrix3.prototype, { + 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 ); + } + } ); + + Object.assign( Matrix4.prototype, { + extractPosition: function ( m ) { + console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + return this.copyPosition( m ); + }, + setRotationFromQuaternion: function ( q ) { + console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + return this.makeRotationFromQuaternion( q ); + }, + multiplyVector3: function ( vector ) { + console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); + return vector.applyProjection( 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 ( v ) { + console.error( 'THREE.Matrix4: .translate() has been removed.' ); + }, + rotateX: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); + }, + rotateY: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); + }, + rotateZ: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); + }, + rotateByAxis: function ( axis, angle ) { + console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); + } + } ); + + Object.assign( Plane.prototype, { + isIntersectionLine: function ( line ) { + console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); + return this.intersectsLine( line ); + } + } ); + + Object.assign( 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( 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 ); + } + } ); + + // + + Object.assign( Object3D.prototype, { + getChildByName: function ( name ) { + console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + return this.getObjectByName( name ); + }, + renderDepth: function ( value ) { + 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 ( value ) { + 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; + } + } + } ); + + // + + 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 ( value ) { + 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 ( value ) { + 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 ( value ) { + 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. Please use .count.' ); + 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( Material.prototype, { + wrapAround: { + get: function () { + console.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' ); + }, + set: function ( value ) { + console.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' ); + } + }, + wrapRGB: { + get: function () { + console.warn( 'THREE.' + this.type + ': .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 ( value ) { + 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; + } + } + } ); + + // + + EventDispatcher.prototype = Object.assign( Object.create( { + + // Note: Extra base ensures these properties are not 'assign'ed. + + constructor: EventDispatcher, + + apply: function ( target ) { + + console.warn( "THREE.EventDispatcher: .apply is deprecated, " + + "just inherit or Object.assign the prototype to mix-in." ); + + Object.assign( target, this ); + + } + + } ), EventDispatcher.prototype ); + + // + + Object.defineProperties( Uniform.prototype, { + dynamic: { + set: function ( value ) { + 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.assign( WebGLRenderer.prototype, { + 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 () { + 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; + } + } + } ); + + // + + Object.assign( Audio.prototype, { + load: function ( file ) { + console.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' ); + var scope = this; + var audioLoader = new AudioLoader(); + audioLoader.load( file, function ( buffer ) { + scope.setBuffer( buffer ); + } ); + return this; + } + } ); + + Object.assign( AudioAnalyser.prototype, { + getData: function ( file ) { + console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); + return this.getFrequencyData(); + } + } ); + + // + + var GeometryUtils = { + + merge: function ( geometry1, geometry2, materialIndexOffset ) { + + console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); + + var matrix; + + if ( geometry2.isMesh ) { + + geometry2.matrixAutoUpdate && geometry2.updateMatrix(); + + matrix = geometry2.matrix; + geometry2 = geometry2.geometry; + + } + + geometry1.merge( geometry2, matrix, materialIndexOffset ); + + }, + + center: function ( geometry ) { + + console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); + return geometry.center(); + + } + + }; + + var ImageUtils = { + + crossOrigin: undefined, + + loadTexture: function ( url, mapping, onLoad, onError ) { + + console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' ); + + var loader = new TextureLoader(); + loader.setCrossOrigin( this.crossOrigin ); + + var texture = loader.load( url, onLoad, undefined, onError ); + + if ( mapping ) texture.mapping = mapping; + + return texture; + + }, + + loadTextureCube: function ( urls, mapping, onLoad, onError ) { + + console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' ); + + var loader = new CubeTextureLoader(); + loader.setCrossOrigin( this.crossOrigin ); + + var texture = loader.load( urls, onLoad, undefined, onError ); + + if ( mapping ) texture.mapping = mapping; + + return texture; + + }, + + loadCompressedTexture: function () { + + console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ); + + }, + + loadCompressedTextureCube: function () { + + console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ); + + } + + }; + + // + + function Projector () { + + console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); + + this.projectVector = function ( vector, camera ) { + + console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); + vector.project( camera ); + + }; + + this.unprojectVector = function ( vector, camera ) { + + console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); + vector.unproject( camera ); + + }; + + this.pickingRay = function ( vector, camera ) { + + console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); + + }; + + } + + // + + function CanvasRenderer () { + + console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); + + this.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + this.clear = function () {}; + this.render = function () {}; + this.setClearColor = function () {}; + this.setSize = function () {}; + + } + + exports.WebGLRenderTargetCube = WebGLRenderTargetCube; + exports.WebGLRenderTarget = WebGLRenderTarget; + exports.WebGLRenderer = WebGLRenderer; + exports.ShaderLib = ShaderLib; + exports.UniformsLib = UniformsLib; + exports.UniformsUtils = UniformsUtils; + exports.ShaderChunk = ShaderChunk; + exports.FogExp2 = FogExp2; + exports.Fog = Fog; + exports.Scene = Scene; + exports.LensFlare = LensFlare; + exports.Sprite = Sprite; + exports.LOD = LOD; + exports.SkinnedMesh = SkinnedMesh; + exports.Skeleton = Skeleton; + exports.Bone = Bone; + exports.Mesh = Mesh; + exports.LineSegments = LineSegments; + exports.Line = Line; + exports.Points = Points; + exports.Group = Group; + exports.VideoTexture = VideoTexture; + exports.DataTexture = DataTexture; + exports.CompressedTexture = CompressedTexture; + exports.CubeTexture = CubeTexture; + exports.CanvasTexture = CanvasTexture; + exports.DepthTexture = DepthTexture; + exports.TextureIdCount = TextureIdCount; + exports.Texture = Texture; + exports.MaterialIdCount = MaterialIdCount; + exports.CompressedTextureLoader = CompressedTextureLoader; + exports.BinaryTextureLoader = BinaryTextureLoader; + exports.DataTextureLoader = DataTextureLoader; + exports.CubeTextureLoader = CubeTextureLoader; + exports.TextureLoader = TextureLoader; + exports.ObjectLoader = ObjectLoader; + exports.MaterialLoader = MaterialLoader; + exports.BufferGeometryLoader = BufferGeometryLoader; + exports.DefaultLoadingManager = DefaultLoadingManager; + exports.LoadingManager = LoadingManager; + exports.JSONLoader = JSONLoader; + exports.ImageLoader = ImageLoader; + exports.FontLoader = FontLoader; + exports.XHRLoader = XHRLoader; + exports.Loader = Loader; + exports.Cache = Cache; + exports.AudioLoader = AudioLoader; + exports.SpotLightShadow = SpotLightShadow; + exports.SpotLight = SpotLight; + exports.PointLight = PointLight; + exports.HemisphereLight = HemisphereLight; + exports.DirectionalLightShadow = DirectionalLightShadow; + exports.DirectionalLight = DirectionalLight; + exports.AmbientLight = AmbientLight; + exports.LightShadow = LightShadow; + exports.Light = Light; + exports.StereoCamera = StereoCamera; + exports.PerspectiveCamera = PerspectiveCamera; + exports.OrthographicCamera = OrthographicCamera; + exports.CubeCamera = CubeCamera; + exports.Camera = Camera; + exports.AudioListener = AudioListener; + exports.PositionalAudio = PositionalAudio; + exports.getAudioContext = getAudioContext; + exports.AudioAnalyser = AudioAnalyser; + exports.Audio = Audio; + exports.VectorKeyframeTrack = VectorKeyframeTrack; + exports.StringKeyframeTrack = StringKeyframeTrack; + exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; + exports.NumberKeyframeTrack = NumberKeyframeTrack; + exports.ColorKeyframeTrack = ColorKeyframeTrack; + exports.BooleanKeyframeTrack = BooleanKeyframeTrack; + exports.PropertyMixer = PropertyMixer; + exports.PropertyBinding = PropertyBinding; + exports.KeyframeTrack = KeyframeTrack; + exports.AnimationUtils = AnimationUtils; + exports.AnimationObjectGroup = AnimationObjectGroup; + exports.AnimationMixer = AnimationMixer; + exports.AnimationClip = AnimationClip; + exports.Uniform = Uniform; + exports.InstancedBufferGeometry = InstancedBufferGeometry; + exports.BufferGeometry = BufferGeometry; + exports.GeometryIdCount = GeometryIdCount; + exports.Geometry = Geometry; + exports.InterleavedBufferAttribute = InterleavedBufferAttribute; + exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; + exports.InterleavedBuffer = InterleavedBuffer; + exports.InstancedBufferAttribute = InstancedBufferAttribute; + exports.DynamicBufferAttribute = DynamicBufferAttribute; + exports.Float64Attribute = Float64Attribute; + exports.Float32Attribute = Float32Attribute; + exports.Uint32Attribute = Uint32Attribute; + exports.Int32Attribute = Int32Attribute; + exports.Uint16Attribute = Uint16Attribute; + exports.Int16Attribute = Int16Attribute; + exports.Uint8ClampedAttribute = Uint8ClampedAttribute; + exports.Uint8Attribute = Uint8Attribute; + exports.Int8Attribute = Int8Attribute; + exports.BufferAttribute = BufferAttribute; + exports.Face3 = Face3; + exports.Object3DIdCount = Object3DIdCount; + exports.Object3D = Object3D; + exports.Raycaster = Raycaster; + exports.Layers = Layers; + exports.EventDispatcher = EventDispatcher; + exports.Clock = Clock; + exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; + exports.LinearInterpolant = LinearInterpolant; + exports.DiscreteInterpolant = DiscreteInterpolant; + exports.CubicInterpolant = CubicInterpolant; + exports.Interpolant = Interpolant; + exports.Triangle = Triangle; + exports.Spline = Spline; + exports.Math = _Math; + exports.Spherical = Spherical; + exports.Plane = Plane; + exports.Frustum = Frustum; + exports.Sphere = Sphere; + exports.Ray = Ray; + exports.Matrix4 = Matrix4; + exports.Matrix3 = Matrix3; + exports.Box3 = Box3; + exports.Box2 = Box2; + exports.Line3 = Line3; + exports.Euler = Euler; + exports.Vector4 = Vector4; + exports.Vector3 = Vector3; + exports.Vector2 = Vector2; + exports.Quaternion = Quaternion; + exports.ColorKeywords = ColorKeywords; + exports.Color = Color; + exports.MorphBlendMesh = MorphBlendMesh; + exports.ImmediateRenderObject = ImmediateRenderObject; + exports.VertexNormalsHelper = VertexNormalsHelper; + exports.SpotLightHelper = SpotLightHelper; + exports.SkeletonHelper = SkeletonHelper; + exports.PointLightHelper = PointLightHelper; + exports.HemisphereLightHelper = HemisphereLightHelper; + exports.GridHelper = GridHelper; + exports.FaceNormalsHelper = FaceNormalsHelper; + exports.DirectionalLightHelper = DirectionalLightHelper; + exports.CameraHelper = CameraHelper; + exports.BoundingBoxHelper = BoundingBoxHelper; + exports.BoxHelper = BoxHelper; + exports.ArrowHelper = ArrowHelper; + exports.AxisHelper = AxisHelper; + exports.ClosedSplineCurve3 = ClosedSplineCurve3; + exports.CatmullRomCurve3 = CatmullRomCurve3; + exports.SplineCurve3 = SplineCurve3; + exports.CubicBezierCurve3 = CubicBezierCurve3; + exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; + exports.LineCurve3 = LineCurve3; + exports.ArcCurve = ArcCurve; + exports.EllipseCurve = EllipseCurve; + exports.SplineCurve = SplineCurve; + exports.CubicBezierCurve = CubicBezierCurve; + exports.QuadraticBezierCurve = QuadraticBezierCurve; + exports.LineCurve = LineCurve; + exports.Shape = Shape; + exports.ShapePath = ShapePath; + exports.Path = Path; + exports.Font = Font; + exports.CurvePath = CurvePath; + exports.Curve = Curve; + exports.ShapeUtils = ShapeUtils; + exports.SceneUtils = SceneUtils; + exports.CurveUtils = CurveUtils; + exports.WireframeGeometry = WireframeGeometry; + exports.ParametricGeometry = ParametricGeometry; + exports.ParametricBufferGeometry = ParametricBufferGeometry; + exports.TetrahedronGeometry = TetrahedronGeometry; + exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; + exports.OctahedronGeometry = OctahedronGeometry; + exports.OctahedronBufferGeometry = OctahedronBufferGeometry; + exports.IcosahedronGeometry = IcosahedronGeometry; + exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; + exports.DodecahedronGeometry = DodecahedronGeometry; + exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; + exports.PolyhedronGeometry = PolyhedronGeometry; + exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; + exports.TubeGeometry = TubeGeometry; + exports.TubeBufferGeometry = TubeBufferGeometry; + exports.TorusKnotGeometry = TorusKnotGeometry; + exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; + exports.TorusGeometry = TorusGeometry; + exports.TorusBufferGeometry = TorusBufferGeometry; + exports.TextGeometry = TextGeometry; + exports.SphereBufferGeometry = SphereBufferGeometry; + exports.SphereGeometry = SphereGeometry; + exports.RingGeometry = RingGeometry; + exports.RingBufferGeometry = RingBufferGeometry; + exports.PlaneBufferGeometry = PlaneBufferGeometry; + exports.PlaneGeometry = PlaneGeometry; + exports.LatheGeometry = LatheGeometry; + exports.LatheBufferGeometry = LatheBufferGeometry; + exports.ShapeGeometry = ShapeGeometry; + exports.ExtrudeGeometry = ExtrudeGeometry; + exports.EdgesGeometry = EdgesGeometry; + exports.ConeGeometry = ConeGeometry; + exports.ConeBufferGeometry = ConeBufferGeometry; + exports.CylinderGeometry = CylinderGeometry; + exports.CylinderBufferGeometry = CylinderBufferGeometry; + exports.CircleBufferGeometry = CircleBufferGeometry; + exports.CircleGeometry = CircleGeometry; + exports.BoxBufferGeometry = BoxBufferGeometry; + exports.BoxGeometry = BoxGeometry; + exports.ShadowMaterial = ShadowMaterial; + exports.SpriteMaterial = SpriteMaterial; + exports.RawShaderMaterial = RawShaderMaterial; + exports.ShaderMaterial = ShaderMaterial; + exports.PointsMaterial = PointsMaterial; + exports.MultiMaterial = MultiMaterial; + exports.MeshPhysicalMaterial = MeshPhysicalMaterial; + exports.MeshStandardMaterial = MeshStandardMaterial; + exports.MeshPhongMaterial = MeshPhongMaterial; + exports.MeshNormalMaterial = MeshNormalMaterial; + exports.MeshLambertMaterial = MeshLambertMaterial; + exports.MeshDepthMaterial = MeshDepthMaterial; + exports.MeshBasicMaterial = MeshBasicMaterial; + exports.LineDashedMaterial = LineDashedMaterial; + exports.LineBasicMaterial = LineBasicMaterial; + exports.Material = Material; + exports.REVISION = REVISION; + exports.MOUSE = MOUSE; + exports.CullFaceNone = CullFaceNone; + exports.CullFaceBack = CullFaceBack; + exports.CullFaceFront = CullFaceFront; + exports.CullFaceFrontBack = CullFaceFrontBack; + exports.FrontFaceDirectionCW = FrontFaceDirectionCW; + exports.FrontFaceDirectionCCW = FrontFaceDirectionCCW; + exports.BasicShadowMap = BasicShadowMap; + exports.PCFShadowMap = PCFShadowMap; + exports.PCFSoftShadowMap = PCFSoftShadowMap; + exports.FrontSide = FrontSide; + exports.BackSide = BackSide; + exports.DoubleSide = DoubleSide; + exports.FlatShading = FlatShading; + exports.SmoothShading = SmoothShading; + exports.NoColors = NoColors; + exports.FaceColors = FaceColors; + exports.VertexColors = VertexColors; + exports.NoBlending = NoBlending; + exports.NormalBlending = NormalBlending; + exports.AdditiveBlending = AdditiveBlending; + exports.SubtractiveBlending = SubtractiveBlending; + exports.MultiplyBlending = MultiplyBlending; + exports.CustomBlending = CustomBlending; + exports.BlendingMode = BlendingMode; + exports.AddEquation = AddEquation; + exports.SubtractEquation = SubtractEquation; + exports.ReverseSubtractEquation = ReverseSubtractEquation; + exports.MinEquation = MinEquation; + exports.MaxEquation = MaxEquation; + exports.ZeroFactor = ZeroFactor; + exports.OneFactor = OneFactor; + exports.SrcColorFactor = SrcColorFactor; + exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor; + exports.SrcAlphaFactor = SrcAlphaFactor; + exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor; + exports.DstAlphaFactor = DstAlphaFactor; + exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; + exports.DstColorFactor = DstColorFactor; + exports.OneMinusDstColorFactor = OneMinusDstColorFactor; + exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; + exports.NeverDepth = NeverDepth; + exports.AlwaysDepth = AlwaysDepth; + exports.LessDepth = LessDepth; + exports.LessEqualDepth = LessEqualDepth; + exports.EqualDepth = EqualDepth; + exports.GreaterEqualDepth = GreaterEqualDepth; + exports.GreaterDepth = GreaterDepth; + exports.NotEqualDepth = NotEqualDepth; + exports.MultiplyOperation = MultiplyOperation; + exports.MixOperation = MixOperation; + exports.AddOperation = AddOperation; + exports.NoToneMapping = NoToneMapping; + exports.LinearToneMapping = LinearToneMapping; + exports.ReinhardToneMapping = ReinhardToneMapping; + exports.Uncharted2ToneMapping = Uncharted2ToneMapping; + exports.CineonToneMapping = CineonToneMapping; + exports.UVMapping = UVMapping; + exports.CubeReflectionMapping = CubeReflectionMapping; + exports.CubeRefractionMapping = CubeRefractionMapping; + exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; + exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; + exports.SphericalReflectionMapping = SphericalReflectionMapping; + exports.CubeUVReflectionMapping = CubeUVReflectionMapping; + exports.CubeUVRefractionMapping = CubeUVRefractionMapping; + exports.TextureMapping = TextureMapping; + exports.RepeatWrapping = RepeatWrapping; + exports.ClampToEdgeWrapping = ClampToEdgeWrapping; + exports.MirroredRepeatWrapping = MirroredRepeatWrapping; + exports.TextureWrapping = TextureWrapping; + exports.NearestFilter = NearestFilter; + exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter; + exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter; + exports.LinearFilter = LinearFilter; + exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter; + exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter; + exports.TextureFilter = TextureFilter; + exports.UnsignedByteType = UnsignedByteType; + exports.ByteType = ByteType; + exports.ShortType = ShortType; + exports.UnsignedShortType = UnsignedShortType; + exports.IntType = IntType; + exports.UnsignedIntType = UnsignedIntType; + exports.FloatType = FloatType; + exports.HalfFloatType = HalfFloatType; + exports.UnsignedShort4444Type = UnsignedShort4444Type; + exports.UnsignedShort5551Type = UnsignedShort5551Type; + exports.UnsignedShort565Type = UnsignedShort565Type; + exports.UnsignedInt248Type = UnsignedInt248Type; + exports.AlphaFormat = AlphaFormat; + exports.RGBFormat = RGBFormat; + exports.RGBAFormat = RGBAFormat; + exports.LuminanceFormat = LuminanceFormat; + exports.LuminanceAlphaFormat = LuminanceAlphaFormat; + exports.RGBEFormat = RGBEFormat; + exports.DepthFormat = DepthFormat; + exports.DepthStencilFormat = DepthStencilFormat; + exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; + exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; + exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; + exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; + exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; + exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; + exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; + exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; + exports.RGB_ETC1_Format = RGB_ETC1_Format; + exports.LoopOnce = LoopOnce; + exports.LoopRepeat = LoopRepeat; + exports.LoopPingPong = LoopPingPong; + exports.InterpolateDiscrete = InterpolateDiscrete; + exports.InterpolateLinear = InterpolateLinear; + exports.InterpolateSmooth = InterpolateSmooth; + exports.ZeroCurvatureEnding = ZeroCurvatureEnding; + exports.ZeroSlopeEnding = ZeroSlopeEnding; + exports.WrapAroundEnding = WrapAroundEnding; + exports.TrianglesDrawMode = TrianglesDrawMode; + exports.TriangleStripDrawMode = TriangleStripDrawMode; + exports.TriangleFanDrawMode = TriangleFanDrawMode; + exports.LinearEncoding = LinearEncoding; + exports.sRGBEncoding = sRGBEncoding; + exports.GammaEncoding = GammaEncoding; + exports.RGBEEncoding = RGBEEncoding; + exports.LogLuvEncoding = LogLuvEncoding; + exports.RGBM7Encoding = RGBM7Encoding; + exports.RGBM16Encoding = RGBM16Encoding; + exports.RGBDEncoding = RGBDEncoding; + exports.BasicDepthPacking = BasicDepthPacking; + exports.RGBADepthPacking = RGBADepthPacking; + exports.CubeGeometry = BoxGeometry; + exports.Face4 = Face4; + exports.LineStrip = LineStrip; + exports.LinePieces = LinePieces; + exports.MeshFaceMaterial = MultiMaterial; + exports.PointCloud = PointCloud; + exports.Particle = Sprite; + exports.ParticleSystem = ParticleSystem; + exports.PointCloudMaterial = PointCloudMaterial; + exports.ParticleBasicMaterial = ParticleBasicMaterial; + exports.ParticleSystemMaterial = ParticleSystemMaterial; + exports.Vertex = Vertex; + exports.EdgesHelper = EdgesHelper; + exports.WireframeHelper = WireframeHelper; + exports.GeometryUtils = GeometryUtils; + exports.ImageUtils = ImageUtils; + exports.Projector = Projector; + exports.CanvasRenderer = CanvasRenderer; + + Object.defineProperty(exports, '__esModule', { value: true }); + + Object.defineProperty( exports, 'AudioContext', { + get: function () { + return exports.getAudioContext(); + } + }); + + }))); + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__.p + "./assets/silver-3da470.bmp"; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _statsJs = __webpack_require__(5); + + var _statsJs2 = _interopRequireDefault(_statsJs); + + var _datGui = __webpack_require__(6); + + var _datGui2 = _interopRequireDefault(_datGui); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var THREE = __webpack_require__(2); + var OrbitControls = __webpack_require__(9)(THREE); + + + // when the scene is done initializing, the function passed as `callback` will be executed + // then, every frame, the function passed as `update` will be executed + function init(callback, update) { + var stats = new _statsJs2.default(); + stats.setMode(1); + stats.domElement.style.position = 'absolute'; + stats.domElement.style.left = '0px'; + stats.domElement.style.top = '0px'; + document.body.appendChild(stats.domElement); + + var gui = new _datGui2.default.GUI({ autoPlace: false }); + + var framework = { + gui: gui, + stats: stats + }; + + // run this function after the window loads + window.addEventListener('load', function () { + + var scene = new THREE.Scene(); + var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); + var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.setClearColor(0x020202, 0); + + var controls = new OrbitControls(camera, renderer.domElement); + controls.enableDamping = true; + controls.enableZoom = true; + controls.target.set(0, 0, 0); + controls.rotateSpeed = 0.3; + controls.zoomSpeed = 1.0; + controls.panSpeed = 2.0; + controls.addEventListener('change', function () { + camera.hasMoved = true; + }); + + document.body.appendChild(renderer.domElement); + + // resize the canvas when the window changes + window.addEventListener('resize', function () { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + }, false); + + // assign THREE.js objects to the object we will return + framework.scene = scene; + framework.camera = camera; + framework.renderer = renderer; + + // begin the animation loop + (function tick() { + stats.begin(); + update(framework); // perform any requested updates + renderer.render(scene, camera); // render the scene + stats.end(); + requestAnimationFrame(tick); // register to call this again when the browser renders a new frame + })(); + + // we will pass the scene, gui, renderer, camera, etc... to the callback function + return callback(framework); + }); + } + + exports.default = { + init: init + }; + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + // stats.js - http://github.com/mrdoob/stats.js + var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; + i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); + k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= + "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= + a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};"object"===typeof module&&(module.exports=Stats); + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(7) + module.exports.color = __webpack_require__(8) + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + /** + * dat-gui JavaScript Controller Library + * http://code.google.com/p/dat-gui + * + * Copyright 2011 Data Arts Team, Google Creative Lab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + /** @namespace */ + var dat = module.exports = dat || {}; + + /** @namespace */ + dat.gui = dat.gui || {}; + + /** @namespace */ + dat.utils = dat.utils || {}; + + /** @namespace */ + dat.controllers = dat.controllers || {}; + + /** @namespace */ + dat.dom = dat.dom || {}; + + /** @namespace */ + dat.color = dat.color || {}; + + dat.utils.css = (function () { + return { + load: function (url, doc) { + doc = doc || document; + var link = doc.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = url; + doc.getElementsByTagName('head')[0].appendChild(link); + }, + inject: function(css, doc) { + doc = doc || document; + var injected = document.createElement('style'); + injected.type = 'text/css'; + injected.innerHTML = css; + doc.getElementsByTagName('head')[0].appendChild(injected); + } + } + })(); + + + dat.utils.common = (function () { + + var ARR_EACH = Array.prototype.forEach; + var ARR_SLICE = Array.prototype.slice; + + /** + * Band-aid methods for things that should be a lot easier in JavaScript. + * Implementation and structure inspired by underscore.js + * http://documentcloud.github.com/underscore/ + */ + + return { + + BREAK: {}, + + extend: function(target) { + + this.each(ARR_SLICE.call(arguments, 1), function(obj) { + + for (var key in obj) + if (!this.isUndefined(obj[key])) + target[key] = obj[key]; + + }, this); + + return target; + + }, + + defaults: function(target) { + + this.each(ARR_SLICE.call(arguments, 1), function(obj) { + + for (var key in obj) + if (this.isUndefined(target[key])) + target[key] = obj[key]; + + }, this); + + return target; + + }, + + compose: function() { + var toCall = ARR_SLICE.call(arguments); + return function() { + var args = ARR_SLICE.call(arguments); + for (var i = toCall.length -1; i >= 0; i--) { + args = [toCall[i].apply(this, args)]; + } + return args[0]; + } + }, + + each: function(obj, itr, scope) { + + + if (ARR_EACH && obj.forEach === ARR_EACH) { + + obj.forEach(itr, scope); + + } else if (obj.length === obj.length + 0) { // Is number but not NaN + + for (var key = 0, l = obj.length; key < l; key++) + if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) + return; + + } else { + + for (var key in obj) + if (itr.call(scope, obj[key], key) === this.BREAK) + return; + + } + + }, + + defer: function(fnc) { + setTimeout(fnc, 0); + }, + + toArray: function(obj) { + if (obj.toArray) return obj.toArray(); + return ARR_SLICE.call(obj); + }, + + isUndefined: function(obj) { + return obj === undefined; + }, + + isNull: function(obj) { + return obj === null; + }, + + isNaN: function(obj) { + return obj !== obj; + }, + + isArray: Array.isArray || function(obj) { + return obj.constructor === Array; + }, + + isObject: function(obj) { + return obj === Object(obj); + }, + + isNumber: function(obj) { + return obj === obj+0; + }, + + isString: function(obj) { + return obj === obj+''; + }, + + isBoolean: function(obj) { + return obj === false || obj === true; + }, + + isFunction: function(obj) { + return Object.prototype.toString.call(obj) === '[object Function]'; + } + + }; + + })(); + + + dat.controllers.Controller = (function (common) { + + /** + * @class An "abstract" class that represents a given property of an object. + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var Controller = function(object, property) { + + this.initialValue = object[property]; + + /** + * Those who extend this class will put their DOM elements in here. + * @type {DOMElement} + */ + this.domElement = document.createElement('div'); + + /** + * The object to manipulate + * @type {Object} + */ + this.object = object; + + /** + * The name of the property to manipulate + * @type {String} + */ + this.property = property; + + /** + * The function to be called on change. + * @type {Function} + * @ignore + */ + this.__onChange = undefined; + + /** + * The function to be called on finishing change. + * @type {Function} + * @ignore + */ + this.__onFinishChange = undefined; + + }; + + common.extend( + + Controller.prototype, + + /** @lends dat.controllers.Controller.prototype */ + { + + /** + * Specify that a function fire every time someone changes the value with + * this Controller. + * + * @param {Function} fnc This function will be called whenever the value + * is modified via this Controller. + * @returns {dat.controllers.Controller} this + */ + onChange: function(fnc) { + this.__onChange = fnc; + return this; + }, + + /** + * Specify that a function fire every time someone "finishes" changing + * the value wih this Controller. Useful for values that change + * incrementally like numbers or strings. + * + * @param {Function} fnc This function will be called whenever + * someone "finishes" changing the value via this Controller. + * @returns {dat.controllers.Controller} this + */ + onFinishChange: function(fnc) { + this.__onFinishChange = fnc; + return this; + }, + + /** + * Change the value of object[property] + * + * @param {Object} newValue The new value of object[property] + */ + setValue: function(newValue) { + this.object[this.property] = newValue; + if (this.__onChange) { + this.__onChange.call(this, newValue); + } + this.updateDisplay(); + return this; + }, + + /** + * Gets the value of object[property] + * + * @returns {Object} The current value of object[property] + */ + getValue: function() { + return this.object[this.property]; + }, + + /** + * Refreshes the visual display of a Controller in order to keep sync + * with the object's current value. + * @returns {dat.controllers.Controller} this + */ + updateDisplay: function() { + return this; + }, + + /** + * @returns {Boolean} true if the value has deviated from initialValue + */ + isModified: function() { + return this.initialValue !== this.getValue() + } + + } + + ); + + return Controller; + + + })(dat.utils.common); + + + dat.dom.dom = (function (common) { + + var EVENT_MAP = { + 'HTMLEvents': ['change'], + 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'], + 'KeyboardEvents': ['keydown'] + }; + + var EVENT_MAP_INV = {}; + common.each(EVENT_MAP, function(v, k) { + common.each(v, function(e) { + EVENT_MAP_INV[e] = k; + }); + }); + + var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/; + + function cssValueToPixels(val) { + + if (val === '0' || common.isUndefined(val)) return 0; + + var match = val.match(CSS_VALUE_PIXELS); + + if (!common.isNull(match)) { + return parseFloat(match[1]); + } + + // TODO ...ems? %? + + return 0; + + } + + /** + * @namespace + * @member dat.dom + */ + var dom = { + + /** + * + * @param elem + * @param selectable + */ + makeSelectable: function(elem, selectable) { + + if (elem === undefined || elem.style === undefined) return; + + elem.onselectstart = selectable ? function() { + return false; + } : function() { + }; + + elem.style.MozUserSelect = selectable ? 'auto' : 'none'; + elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none'; + elem.unselectable = selectable ? 'on' : 'off'; + + }, + + /** + * + * @param elem + * @param horizontal + * @param vertical + */ + makeFullscreen: function(elem, horizontal, vertical) { + + if (common.isUndefined(horizontal)) horizontal = true; + if (common.isUndefined(vertical)) vertical = true; + + elem.style.position = 'absolute'; + + if (horizontal) { + elem.style.left = 0; + elem.style.right = 0; + } + if (vertical) { + elem.style.top = 0; + elem.style.bottom = 0; + } + + }, + + /** + * + * @param elem + * @param eventType + * @param params + */ + fakeEvent: function(elem, eventType, params, aux) { + params = params || {}; + var className = EVENT_MAP_INV[eventType]; + if (!className) { + throw new Error('Event type ' + eventType + ' not supported.'); + } + var evt = document.createEvent(className); + switch (className) { + case 'MouseEvents': + var clientX = params.x || params.clientX || 0; + var clientY = params.y || params.clientY || 0; + evt.initMouseEvent(eventType, params.bubbles || false, + params.cancelable || true, window, params.clickCount || 1, + 0, //screen X + 0, //screen Y + clientX, //client X + clientY, //client Y + false, false, false, false, 0, null); + break; + case 'KeyboardEvents': + var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz + common.defaults(params, { + cancelable: true, + ctrlKey: false, + altKey: false, + shiftKey: false, + metaKey: false, + keyCode: undefined, + charCode: undefined + }); + init(eventType, params.bubbles || false, + params.cancelable, window, + params.ctrlKey, params.altKey, + params.shiftKey, params.metaKey, + params.keyCode, params.charCode); + break; + default: + evt.initEvent(eventType, params.bubbles || false, + params.cancelable || true); + break; + } + common.defaults(evt, aux); + elem.dispatchEvent(evt); + }, + + /** + * + * @param elem + * @param event + * @param func + * @param bool + */ + bind: function(elem, event, func, bool) { + bool = bool || false; + if (elem.addEventListener) + elem.addEventListener(event, func, bool); + else if (elem.attachEvent) + elem.attachEvent('on' + event, func); + return dom; + }, + + /** + * + * @param elem + * @param event + * @param func + * @param bool + */ + unbind: function(elem, event, func, bool) { + bool = bool || false; + if (elem.removeEventListener) + elem.removeEventListener(event, func, bool); + else if (elem.detachEvent) + elem.detachEvent('on' + event, func); + return dom; + }, + + /** + * + * @param elem + * @param className + */ + addClass: function(elem, className) { + if (elem.className === undefined) { + elem.className = className; + } else if (elem.className !== className) { + var classes = elem.className.split(/ +/); + if (classes.indexOf(className) == -1) { + classes.push(className); + elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, ''); + } + } + return dom; + }, + + /** + * + * @param elem + * @param className + */ + removeClass: function(elem, className) { + if (className) { + if (elem.className === undefined) { + // elem.className = className; + } else if (elem.className === className) { + elem.removeAttribute('class'); + } else { + var classes = elem.className.split(/ +/); + var index = classes.indexOf(className); + if (index != -1) { + classes.splice(index, 1); + elem.className = classes.join(' '); + } + } + } else { + elem.className = undefined; + } + return dom; + }, + + hasClass: function(elem, className) { + return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false; + }, + + /** + * + * @param elem + */ + getWidth: function(elem) { + + var style = getComputedStyle(elem); + + return cssValueToPixels(style['border-left-width']) + + cssValueToPixels(style['border-right-width']) + + cssValueToPixels(style['padding-left']) + + cssValueToPixels(style['padding-right']) + + cssValueToPixels(style['width']); + }, + + /** + * + * @param elem + */ + getHeight: function(elem) { + + var style = getComputedStyle(elem); + + return cssValueToPixels(style['border-top-width']) + + cssValueToPixels(style['border-bottom-width']) + + cssValueToPixels(style['padding-top']) + + cssValueToPixels(style['padding-bottom']) + + cssValueToPixels(style['height']); + }, + + /** + * + * @param elem + */ + getOffset: function(elem) { + var offset = {left: 0, top:0}; + if (elem.offsetParent) { + do { + offset.left += elem.offsetLeft; + offset.top += elem.offsetTop; + } while (elem = elem.offsetParent); + } + return offset; + }, + + // http://stackoverflow.com/posts/2684561/revisions + /** + * + * @param elem + */ + isActive: function(elem) { + return elem === document.activeElement && ( elem.type || elem.href ); + } + + }; + + return dom; + + })(dat.utils.common); + + + dat.controllers.OptionController = (function (Controller, dom, common) { + + /** + * @class Provides a select input to alter the property of an object, using a + * list of accepted values. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * @param {Object|string[]} options A map of labels to acceptable values, or + * a list of acceptable string values. + * + * @member dat.controllers + */ + var OptionController = function(object, property, options) { + + OptionController.superclass.call(this, object, property); + + var _this = this; + + /** + * The drop down menu + * @ignore + */ + this.__select = document.createElement('select'); + + if (common.isArray(options)) { + var map = {}; + common.each(options, function(element) { + map[element] = element; + }); + options = map; + } + + common.each(options, function(value, key) { + + var opt = document.createElement('option'); + opt.innerHTML = key; + opt.setAttribute('value', value); + _this.__select.appendChild(opt); + + }); + + // Acknowledge original value + this.updateDisplay(); + + dom.bind(this.__select, 'change', function() { + var desiredValue = this.options[this.selectedIndex].value; + _this.setValue(desiredValue); + }); + + this.domElement.appendChild(this.__select); + + }; + + OptionController.superclass = Controller; + + common.extend( + + OptionController.prototype, + Controller.prototype, + + { + + setValue: function(v) { + var toReturn = OptionController.superclass.prototype.setValue.call(this, v); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + return toReturn; + }, + + updateDisplay: function() { + this.__select.value = this.getValue(); + return OptionController.superclass.prototype.updateDisplay.call(this); + } + + } + + ); + + return OptionController; + + })(dat.controllers.Controller, + dat.dom.dom, + dat.utils.common); + + + dat.controllers.NumberController = (function (Controller, common) { + + /** + * @class Represents a given property of an object that is a number. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * @param {Object} [params] Optional parameters + * @param {Number} [params.min] Minimum allowed value + * @param {Number} [params.max] Maximum allowed value + * @param {Number} [params.step] Increment by which to change value + * + * @member dat.controllers + */ + var NumberController = function(object, property, params) { + + NumberController.superclass.call(this, object, property); + + params = params || {}; + + this.__min = params.min; + this.__max = params.max; + this.__step = params.step; + + if (common.isUndefined(this.__step)) { + + if (this.initialValue == 0) { + this.__impliedStep = 1; // What are we, psychics? + } else { + // Hey Doug, check this out. + this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10; + } + + } else { + + this.__impliedStep = this.__step; + + } + + this.__precision = numDecimals(this.__impliedStep); + + + }; + + NumberController.superclass = Controller; + + common.extend( + + NumberController.prototype, + Controller.prototype, + + /** @lends dat.controllers.NumberController.prototype */ + { + + setValue: function(v) { + + if (this.__min !== undefined && v < this.__min) { + v = this.__min; + } else if (this.__max !== undefined && v > this.__max) { + v = this.__max; + } + + if (this.__step !== undefined && v % this.__step != 0) { + v = Math.round(v / this.__step) * this.__step; + } + + return NumberController.superclass.prototype.setValue.call(this, v); + + }, + + /** + * Specify a minimum value for object[property]. + * + * @param {Number} minValue The minimum value for + * object[property] + * @returns {dat.controllers.NumberController} this + */ + min: function(v) { + this.__min = v; + return this; + }, + + /** + * Specify a maximum value for object[property]. + * + * @param {Number} maxValue The maximum value for + * object[property] + * @returns {dat.controllers.NumberController} this + */ + max: function(v) { + this.__max = v; + return this; + }, + + /** + * Specify a step value that dat.controllers.NumberController + * increments by. + * + * @param {Number} stepValue The step value for + * dat.controllers.NumberController + * @default if minimum and maximum specified increment is 1% of the + * difference otherwise stepValue is 1 + * @returns {dat.controllers.NumberController} this + */ + step: function(v) { + this.__step = v; + return this; + } + + } + + ); + + function numDecimals(x) { + x = x.toString(); + if (x.indexOf('.') > -1) { + return x.length - x.indexOf('.') - 1; + } else { + return 0; + } + } + + return NumberController; + + })(dat.controllers.Controller, + dat.utils.common); + + + dat.controllers.NumberControllerBox = (function (NumberController, dom, common) { + + /** + * @class Represents a given property of an object that is a number and + * provides an input element with which to manipulate it. + * + * @extends dat.controllers.Controller + * @extends dat.controllers.NumberController + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * @param {Object} [params] Optional parameters + * @param {Number} [params.min] Minimum allowed value + * @param {Number} [params.max] Maximum allowed value + * @param {Number} [params.step] Increment by which to change value + * + * @member dat.controllers + */ + var NumberControllerBox = function(object, property, params) { + + this.__truncationSuspended = false; + + NumberControllerBox.superclass.call(this, object, property, params); + + var _this = this; + + /** + * {Number} Previous mouse y position + * @ignore + */ + var prev_y; + + this.__input = document.createElement('input'); + this.__input.setAttribute('type', 'text'); + + // Makes it so manually specified values are not truncated. + + dom.bind(this.__input, 'change', onChange); + dom.bind(this.__input, 'blur', onBlur); + dom.bind(this.__input, 'mousedown', onMouseDown); + dom.bind(this.__input, 'keydown', function(e) { + + // When pressing entire, you can be as precise as you want. + if (e.keyCode === 13) { + _this.__truncationSuspended = true; + this.blur(); + _this.__truncationSuspended = false; + } + + }); + + function onChange() { + var attempted = parseFloat(_this.__input.value); + if (!common.isNaN(attempted)) _this.setValue(attempted); + } + + function onBlur() { + onChange(); + if (_this.__onFinishChange) { + _this.__onFinishChange.call(_this, _this.getValue()); + } + } + + function onMouseDown(e) { + dom.bind(window, 'mousemove', onMouseDrag); + dom.bind(window, 'mouseup', onMouseUp); + prev_y = e.clientY; + } + + function onMouseDrag(e) { + + var diff = prev_y - e.clientY; + _this.setValue(_this.getValue() + diff * _this.__impliedStep); + + prev_y = e.clientY; + + } + + function onMouseUp() { + dom.unbind(window, 'mousemove', onMouseDrag); + dom.unbind(window, 'mouseup', onMouseUp); + } + + this.updateDisplay(); + + this.domElement.appendChild(this.__input); + + }; + + NumberControllerBox.superclass = NumberController; + + common.extend( + + NumberControllerBox.prototype, + NumberController.prototype, + + { + + updateDisplay: function() { + + this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision); + return NumberControllerBox.superclass.prototype.updateDisplay.call(this); + } + + } + + ); + + function roundToDecimal(value, decimals) { + var tenTo = Math.pow(10, decimals); + return Math.round(value * tenTo) / tenTo; + } + + return NumberControllerBox; + + })(dat.controllers.NumberController, + dat.dom.dom, + dat.utils.common); + + + dat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) { + + /** + * @class Represents a given property of an object that is a number, contains + * a minimum and maximum, and provides a slider element with which to + * manipulate it. It should be noted that the slider element is made up of + * <div> tags, not the html5 + * <slider> element. + * + * @extends dat.controllers.Controller + * @extends dat.controllers.NumberController + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * @param {Number} minValue Minimum allowed value + * @param {Number} maxValue Maximum allowed value + * @param {Number} stepValue Increment by which to change value + * + * @member dat.controllers + */ + var NumberControllerSlider = function(object, property, min, max, step) { + + NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step }); + + var _this = this; + + this.__background = document.createElement('div'); + this.__foreground = document.createElement('div'); + + + + dom.bind(this.__background, 'mousedown', onMouseDown); + + dom.addClass(this.__background, 'slider'); + dom.addClass(this.__foreground, 'slider-fg'); + + function onMouseDown(e) { + + dom.bind(window, 'mousemove', onMouseDrag); + dom.bind(window, 'mouseup', onMouseUp); + + onMouseDrag(e); + } + + function onMouseDrag(e) { + + e.preventDefault(); + + var offset = dom.getOffset(_this.__background); + var width = dom.getWidth(_this.__background); + + _this.setValue( + map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max) + ); + + return false; + + } + + function onMouseUp() { + dom.unbind(window, 'mousemove', onMouseDrag); + dom.unbind(window, 'mouseup', onMouseUp); + if (_this.__onFinishChange) { + _this.__onFinishChange.call(_this, _this.getValue()); + } + } + + this.updateDisplay(); + + this.__background.appendChild(this.__foreground); + this.domElement.appendChild(this.__background); + + }; + + NumberControllerSlider.superclass = NumberController; + + /** + * Injects default stylesheet for slider elements. + */ + NumberControllerSlider.useDefaultStyles = function() { + css.inject(styleSheet); + }; + + common.extend( + + NumberControllerSlider.prototype, + NumberController.prototype, + + { + + updateDisplay: function() { + var pct = (this.getValue() - this.__min)/(this.__max - this.__min); + this.__foreground.style.width = pct*100+'%'; + return NumberControllerSlider.superclass.prototype.updateDisplay.call(this); + } + + } + + + + ); + + function map(v, i1, i2, o1, o2) { + return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); + } + + return NumberControllerSlider; + + })(dat.controllers.NumberController, + dat.dom.dom, + dat.utils.css, + dat.utils.common, + ".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); + + + dat.controllers.FunctionController = (function (Controller, dom, common) { + + /** + * @class Provides a GUI interface to fire a specified method, a property of an object. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var FunctionController = function(object, property, text) { + + FunctionController.superclass.call(this, object, property); + + var _this = this; + + this.__button = document.createElement('div'); + this.__button.innerHTML = text === undefined ? 'Fire' : text; + dom.bind(this.__button, 'click', function(e) { + e.preventDefault(); + _this.fire(); + return false; + }); + + dom.addClass(this.__button, 'button'); + + this.domElement.appendChild(this.__button); + + + }; + + FunctionController.superclass = Controller; + + common.extend( + + FunctionController.prototype, + Controller.prototype, + { + + fire: function() { + if (this.__onChange) { + this.__onChange.call(this); + } + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + this.getValue().call(this.object); + } + } + + ); + + return FunctionController; + + })(dat.controllers.Controller, + dat.dom.dom, + dat.utils.common); + + + dat.controllers.BooleanController = (function (Controller, dom, common) { + + /** + * @class Provides a checkbox input to alter the boolean property of an object. + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var BooleanController = function(object, property) { + + BooleanController.superclass.call(this, object, property); + + var _this = this; + this.__prev = this.getValue(); + + this.__checkbox = document.createElement('input'); + this.__checkbox.setAttribute('type', 'checkbox'); + + + dom.bind(this.__checkbox, 'change', onChange, false); + + this.domElement.appendChild(this.__checkbox); + + // Match original value + this.updateDisplay(); + + function onChange() { + _this.setValue(!_this.__prev); + } + + }; + + BooleanController.superclass = Controller; + + common.extend( + + BooleanController.prototype, + Controller.prototype, + + { + + setValue: function(v) { + var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + this.__prev = this.getValue(); + return toReturn; + }, + + updateDisplay: function() { + + if (this.getValue() === true) { + this.__checkbox.setAttribute('checked', 'checked'); + this.__checkbox.checked = true; + } else { + this.__checkbox.checked = false; + } + + return BooleanController.superclass.prototype.updateDisplay.call(this); + + } + + + } + + ); + + return BooleanController; + + })(dat.controllers.Controller, + dat.dom.dom, + dat.utils.common); + + + dat.color.toString = (function (common) { + + return function(color) { + + if (color.a == 1 || common.isUndefined(color.a)) { + + var s = color.hex.toString(16); + while (s.length < 6) { + s = '0' + s; + } + + return '#' + s; + + } else { + + return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')'; + + } + + } + + })(dat.utils.common); + + + dat.color.interpret = (function (toString, common) { + + var result, toReturn; + + var interpret = function() { + + toReturn = false; + + var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0]; + + common.each(INTERPRETATIONS, function(family) { + + if (family.litmus(original)) { + + common.each(family.conversions, function(conversion, conversionName) { + + result = conversion.read(original); + + if (toReturn === false && result !== false) { + toReturn = result; + result.conversionName = conversionName; + result.conversion = conversion; + return common.BREAK; + + } + + }); + + return common.BREAK; + + } + + }); + + return toReturn; + + }; + + var INTERPRETATIONS = [ + + // Strings + { + + litmus: common.isString, + + conversions: { + + THREE_CHAR_HEX: { + + read: function(original) { + + var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i); + if (test === null) return false; + + return { + space: 'HEX', + hex: parseInt( + '0x' + + test[1].toString() + test[1].toString() + + test[2].toString() + test[2].toString() + + test[3].toString() + test[3].toString()) + }; + + }, + + write: toString + + }, + + SIX_CHAR_HEX: { + + read: function(original) { + + var test = original.match(/^#([A-F0-9]{6})$/i); + if (test === null) return false; + + return { + space: 'HEX', + hex: parseInt('0x' + test[1].toString()) + }; + + }, + + write: toString + + }, + + CSS_RGB: { + + read: function(original) { + + var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); + if (test === null) return false; + + return { + space: 'RGB', + r: parseFloat(test[1]), + g: parseFloat(test[2]), + b: parseFloat(test[3]) + }; + + }, + + write: toString + + }, + + CSS_RGBA: { + + read: function(original) { + + var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/); + if (test === null) return false; + + return { + space: 'RGB', + r: parseFloat(test[1]), + g: parseFloat(test[2]), + b: parseFloat(test[3]), + a: parseFloat(test[4]) + }; + + }, + + write: toString + + } + + } + + }, + + // Numbers + { + + litmus: common.isNumber, + + conversions: { + + HEX: { + read: function(original) { + return { + space: 'HEX', + hex: original, + conversionName: 'HEX' + } + }, + + write: function(color) { + return color.hex; + } + } + + } + + }, + + // Arrays + { + + litmus: common.isArray, + + conversions: { + + RGB_ARRAY: { + read: function(original) { + if (original.length != 3) return false; + return { + space: 'RGB', + r: original[0], + g: original[1], + b: original[2] + }; + }, + + write: function(color) { + return [color.r, color.g, color.b]; + } + + }, + + RGBA_ARRAY: { + read: function(original) { + if (original.length != 4) return false; + return { + space: 'RGB', + r: original[0], + g: original[1], + b: original[2], + a: original[3] + }; + }, + + write: function(color) { + return [color.r, color.g, color.b, color.a]; + } + + } + + } + + }, + + // Objects + { + + litmus: common.isObject, + + conversions: { + + RGBA_OBJ: { + read: function(original) { + if (common.isNumber(original.r) && + common.isNumber(original.g) && + common.isNumber(original.b) && + common.isNumber(original.a)) { + return { + space: 'RGB', + r: original.r, + g: original.g, + b: original.b, + a: original.a + } + } + return false; + }, + + write: function(color) { + return { + r: color.r, + g: color.g, + b: color.b, + a: color.a + } + } + }, + + RGB_OBJ: { + read: function(original) { + if (common.isNumber(original.r) && + common.isNumber(original.g) && + common.isNumber(original.b)) { + return { + space: 'RGB', + r: original.r, + g: original.g, + b: original.b + } + } + return false; + }, + + write: function(color) { + return { + r: color.r, + g: color.g, + b: color.b + } + } + }, + + HSVA_OBJ: { + read: function(original) { + if (common.isNumber(original.h) && + common.isNumber(original.s) && + common.isNumber(original.v) && + common.isNumber(original.a)) { + return { + space: 'HSV', + h: original.h, + s: original.s, + v: original.v, + a: original.a + } + } + return false; + }, + + write: function(color) { + return { + h: color.h, + s: color.s, + v: color.v, + a: color.a + } + } + }, + + HSV_OBJ: { + read: function(original) { + if (common.isNumber(original.h) && + common.isNumber(original.s) && + common.isNumber(original.v)) { + return { + space: 'HSV', + h: original.h, + s: original.s, + v: original.v + } + } + return false; + }, + + write: function(color) { + return { + h: color.h, + s: color.s, + v: color.v + } + } + + } + + } + + } + + + ]; + + return interpret; + + + })(dat.color.toString, + dat.utils.common); + + + dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) { + + css.inject(styleSheet); + + /** Outer-most className for GUI's */ + var CSS_NAMESPACE = 'dg'; + + var HIDE_KEY_CODE = 72; + + /** The only value shared between the JS and SCSS. Use caution. */ + var CLOSE_BUTTON_HEIGHT = 20; + + var DEFAULT_DEFAULT_PRESET_NAME = 'Default'; + + var SUPPORTS_LOCAL_STORAGE = (function() { + try { + return 'localStorage' in window && window['localStorage'] !== null; + } catch (e) { + return false; + } + })(); + + var SAVE_DIALOGUE; + + /** Have we yet to create an autoPlace GUI? */ + var auto_place_virgin = true; + + /** Fixed position div that auto place GUI's go inside */ + var auto_place_container; + + /** Are we hiding the GUI's ? */ + var hide = false; + + /** GUI's which should be hidden */ + var hideable_guis = []; + + /** + * A lightweight controller library for JavaScript. It allows you to easily + * manipulate variables and fire functions on the fly. + * @class + * + * @member dat.gui + * + * @param {Object} [params] + * @param {String} [params.name] The name of this GUI. + * @param {Object} [params.load] JSON object representing the saved state of + * this GUI. + * @param {Boolean} [params.auto=true] + * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in. + * @param {Boolean} [params.closed] If true, starts closed + */ + var GUI = function(params) { + + var _this = this; + + /** + * Outermost DOM Element + * @type DOMElement + */ + this.domElement = document.createElement('div'); + this.__ul = document.createElement('ul'); + this.domElement.appendChild(this.__ul); + + dom.addClass(this.domElement, CSS_NAMESPACE); + + /** + * Nested GUI's by name + * @ignore + */ + this.__folders = {}; + + this.__controllers = []; + + /** + * List of objects I'm remembering for save, only used in top level GUI + * @ignore + */ + this.__rememberedObjects = []; + + /** + * Maps the index of remembered objects to a map of controllers, only used + * in top level GUI. + * + * @private + * @ignore + * + * @example + * [ + * { + * propertyName: Controller, + * anotherPropertyName: Controller + * }, + * { + * propertyName: Controller + * } + * ] + */ + this.__rememberedObjectIndecesToControllers = []; + + this.__listening = []; + + params = params || {}; + + // Default parameters + params = common.defaults(params, { + autoPlace: true, + width: GUI.DEFAULT_WIDTH + }); + + params = common.defaults(params, { + resizable: params.autoPlace, + hideable: params.autoPlace + }); + + + if (!common.isUndefined(params.load)) { + + // Explicit preset + if (params.preset) params.load.preset = params.preset; + + } else { + + params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME }; + + } + + if (common.isUndefined(params.parent) && params.hideable) { + hideable_guis.push(this); + } + + // Only root level GUI's are resizable. + params.resizable = common.isUndefined(params.parent) && params.resizable; + + + if (params.autoPlace && common.isUndefined(params.scrollable)) { + params.scrollable = true; + } + // params.scrollable = common.isUndefined(params.parent) && params.scrollable === true; + + // Not part of params because I don't want people passing this in via + // constructor. Should be a 'remembered' value. + var use_local_storage = + SUPPORTS_LOCAL_STORAGE && + localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true'; + + Object.defineProperties(this, + + /** @lends dat.gui.GUI.prototype */ + { + + /** + * The parent GUI + * @type dat.gui.GUI + */ + parent: { + get: function() { + return params.parent; + } + }, + + scrollable: { + get: function() { + return params.scrollable; + } + }, + + /** + * Handles GUI's element placement for you + * @type Boolean + */ + autoPlace: { + get: function() { + return params.autoPlace; + } + }, + + /** + * The identifier for a set of saved values + * @type String + */ + preset: { + + get: function() { + if (_this.parent) { + return _this.getRoot().preset; + } else { + return params.load.preset; + } + }, + + set: function(v) { + if (_this.parent) { + _this.getRoot().preset = v; + } else { + params.load.preset = v; + } + setPresetSelectIndex(this); + _this.revert(); + } + + }, + + /** + * The width of GUI element + * @type Number + */ + width: { + get: function() { + return params.width; + }, + set: function(v) { + params.width = v; + setWidth(_this, v); + } + }, + + /** + * The name of GUI. Used for folders. i.e + * a folder's name + * @type String + */ + name: { + get: function() { + return params.name; + }, + set: function(v) { + // TODO Check for collisions among sibling folders + params.name = v; + if (title_row_name) { + title_row_name.innerHTML = params.name; + } + } + }, + + /** + * Whether the GUI is collapsed or not + * @type Boolean + */ + closed: { + get: function() { + return params.closed; + }, + set: function(v) { + params.closed = v; + if (params.closed) { + dom.addClass(_this.__ul, GUI.CLASS_CLOSED); + } else { + dom.removeClass(_this.__ul, GUI.CLASS_CLOSED); + } + // For browsers that aren't going to respect the CSS transition, + // Lets just check our height against the window height right off + // the bat. + this.onResize(); + + if (_this.__closeButton) { + _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED; + } + } + }, + + /** + * Contains all presets + * @type Object + */ + load: { + get: function() { + return params.load; + } + }, + + /** + * Determines whether or not to use localStorage as the means for + * remembering + * @type Boolean + */ + useLocalStorage: { + + get: function() { + return use_local_storage; + }, + set: function(bool) { + if (SUPPORTS_LOCAL_STORAGE) { + use_local_storage = bool; + if (bool) { + dom.bind(window, 'unload', saveToLocalStorage); + } else { + dom.unbind(window, 'unload', saveToLocalStorage); + } + localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool); + } + } + + } + + }); + + // Are we a root level GUI? + if (common.isUndefined(params.parent)) { + + params.closed = false; + + dom.addClass(this.domElement, GUI.CLASS_MAIN); + dom.makeSelectable(this.domElement, false); + + // Are we supposed to be loading locally? + if (SUPPORTS_LOCAL_STORAGE) { + + if (use_local_storage) { + + _this.useLocalStorage = true; + + var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui')); + + if (saved_gui) { + params.load = JSON.parse(saved_gui); + } + + } + + } + + this.__closeButton = document.createElement('div'); + this.__closeButton.innerHTML = GUI.TEXT_CLOSED; + dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON); + this.domElement.appendChild(this.__closeButton); + + dom.bind(this.__closeButton, 'click', function() { + + _this.closed = !_this.closed; + + + }); + + + // Oh, you're a nested GUI! + } else { + + if (params.closed === undefined) { + params.closed = true; + } + + var title_row_name = document.createTextNode(params.name); + dom.addClass(title_row_name, 'controller-name'); + + var title_row = addRow(_this, title_row_name); + + var on_click_title = function(e) { + e.preventDefault(); + _this.closed = !_this.closed; + return false; + }; + + dom.addClass(this.__ul, GUI.CLASS_CLOSED); + + dom.addClass(title_row, 'title'); + dom.bind(title_row, 'click', on_click_title); + + if (!params.closed) { + this.closed = false; + } + + } + + if (params.autoPlace) { + + if (common.isUndefined(params.parent)) { + + if (auto_place_virgin) { + auto_place_container = document.createElement('div'); + dom.addClass(auto_place_container, CSS_NAMESPACE); + dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER); + document.body.appendChild(auto_place_container); + auto_place_virgin = false; + } + + // Put it in the dom for you. + auto_place_container.appendChild(this.domElement); + + // Apply the auto styles + dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE); + + } + + + // Make it not elastic. + if (!this.parent) setWidth(_this, params.width); + + } + + dom.bind(window, 'resize', function() { _this.onResize() }); + dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); }); + dom.bind(this.__ul, 'transitionend', function() { _this.onResize() }); + dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() }); + this.onResize(); + + + if (params.resizable) { + addResizeHandle(this); + } + + function saveToLocalStorage() { + localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject())); + } + + var root = _this.getRoot(); + function resetWidth() { + var root = _this.getRoot(); + root.width += 1; + common.defer(function() { + root.width -= 1; + }); + } + + if (!params.parent) { + resetWidth(); + } + + }; + + GUI.toggleHide = function() { + + hide = !hide; + common.each(hideable_guis, function(gui) { + gui.domElement.style.zIndex = hide ? -999 : 999; + gui.domElement.style.opacity = hide ? 0 : 1; + }); + }; + + GUI.CLASS_AUTO_PLACE = 'a'; + GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac'; + GUI.CLASS_MAIN = 'main'; + GUI.CLASS_CONTROLLER_ROW = 'cr'; + GUI.CLASS_TOO_TALL = 'taller-than-window'; + GUI.CLASS_CLOSED = 'closed'; + GUI.CLASS_CLOSE_BUTTON = 'close-button'; + GUI.CLASS_DRAG = 'drag'; + + GUI.DEFAULT_WIDTH = 245; + GUI.TEXT_CLOSED = 'Close Controls'; + GUI.TEXT_OPEN = 'Open Controls'; + + dom.bind(window, 'keydown', function(e) { + + if (document.activeElement.type !== 'text' && + (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) { + GUI.toggleHide(); + } + + }, false); + + common.extend( + + GUI.prototype, + + /** @lends dat.gui.GUI */ + { + + /** + * @param object + * @param property + * @returns {dat.controllers.Controller} The new controller that was added. + * @instance + */ + add: function(object, property) { + + return add( + this, + object, + property, + { + factoryArgs: Array.prototype.slice.call(arguments, 2) + } + ); + + }, + + /** + * @param object + * @param property + * @returns {dat.controllers.ColorController} The new controller that was added. + * @instance + */ + addColor: function(object, property) { + + return add( + this, + object, + property, + { + color: true + } + ); + + }, + + /** + * @param controller + * @instance + */ + remove: function(controller) { + + // TODO listening? + this.__ul.removeChild(controller.__li); + this.__controllers.slice(this.__controllers.indexOf(controller), 1); + var _this = this; + common.defer(function() { + _this.onResize(); + }); + + }, + + destroy: function() { + + if (this.autoPlace) { + auto_place_container.removeChild(this.domElement); + } + + }, + + /** + * @param name + * @returns {dat.gui.GUI} The new folder. + * @throws {Error} if this GUI already has a folder by the specified + * name + * @instance + */ + addFolder: function(name) { + + // We have to prevent collisions on names in order to have a key + // by which to remember saved values + if (this.__folders[name] !== undefined) { + throw new Error('You already have a folder in this GUI by the' + + ' name "' + name + '"'); + } + + var new_gui_params = { name: name, parent: this }; + + // We need to pass down the autoPlace trait so that we can + // attach event listeners to open/close folder actions to + // ensure that a scrollbar appears if the window is too short. + new_gui_params.autoPlace = this.autoPlace; + + // Do we have saved appearance data for this folder? + + if (this.load && // Anything loaded? + this.load.folders && // Was my parent a dead-end? + this.load.folders[name]) { // Did daddy remember me? + + // Start me closed if I was closed + new_gui_params.closed = this.load.folders[name].closed; + + // Pass down the loaded data + new_gui_params.load = this.load.folders[name]; + + } + + var gui = new GUI(new_gui_params); + this.__folders[name] = gui; + + var li = addRow(this, gui.domElement); + dom.addClass(li, 'folder'); + return gui; + + }, + + open: function() { + this.closed = false; + }, + + close: function() { + this.closed = true; + }, + + onResize: function() { + + var root = this.getRoot(); + + if (root.scrollable) { + + var top = dom.getOffset(root.__ul).top; + var h = 0; + + common.each(root.__ul.childNodes, function(node) { + if (! (root.autoPlace && node === root.__save_row)) + h += dom.getHeight(node); + }); + + if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) { + dom.addClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px'; + } else { + dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = 'auto'; + } + + } + + if (root.__resize_handle) { + common.defer(function() { + root.__resize_handle.style.height = root.__ul.offsetHeight + 'px'; + }); + } + + if (root.__closeButton) { + root.__closeButton.style.width = root.width + 'px'; + } + + }, + + /** + * Mark objects for saving. The order of these objects cannot change as + * the GUI grows. When remembering new objects, append them to the end + * of the list. + * + * @param {Object...} objects + * @throws {Error} if not called on a top level GUI. + * @instance + */ + remember: function() { + + if (common.isUndefined(SAVE_DIALOGUE)) { + SAVE_DIALOGUE = new CenteredDiv(); + SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents; + } + + if (this.parent) { + throw new Error("You can only call remember on a top level GUI."); + } + + var _this = this; + + common.each(Array.prototype.slice.call(arguments), function(object) { + if (_this.__rememberedObjects.length == 0) { + addSaveMenu(_this); + } + if (_this.__rememberedObjects.indexOf(object) == -1) { + _this.__rememberedObjects.push(object); + } + }); + + if (this.autoPlace) { + // Set save row width + setWidth(this, this.width); + } + + }, + + /** + * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI. + * @instance + */ + getRoot: function() { + var gui = this; + while (gui.parent) { + gui = gui.parent; + } + return gui; + }, + + /** + * @returns {Object} a JSON object representing the current state of + * this GUI as well as its remembered properties. + * @instance + */ + getSaveObject: function() { + + var toReturn = this.load; + + toReturn.closed = this.closed; + + // Am I remembering any values? + if (this.__rememberedObjects.length > 0) { + + toReturn.preset = this.preset; + + if (!toReturn.remembered) { + toReturn.remembered = {}; + } + + toReturn.remembered[this.preset] = getCurrentPreset(this); + + } + + toReturn.folders = {}; + common.each(this.__folders, function(element, key) { + toReturn.folders[key] = element.getSaveObject(); + }); + + return toReturn; + + }, + + save: function() { + + if (!this.load.remembered) { + this.load.remembered = {}; + } + + this.load.remembered[this.preset] = getCurrentPreset(this); + markPresetModified(this, false); + + }, + + saveAs: function(presetName) { + + if (!this.load.remembered) { + + // Retain default values upon first save + this.load.remembered = {}; + this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true); + + } + + this.load.remembered[presetName] = getCurrentPreset(this); + this.preset = presetName; + addPresetOption(this, presetName, true); + + }, + + revert: function(gui) { + + common.each(this.__controllers, function(controller) { + // Make revert work on Default. + if (!this.getRoot().load.remembered) { + controller.setValue(controller.initialValue); + } else { + recallSavedValue(gui || this.getRoot(), controller); + } + }, this); + + common.each(this.__folders, function(folder) { + folder.revert(folder); + }); + + if (!gui) { + markPresetModified(this.getRoot(), false); + } + + + }, + + listen: function(controller) { + + var init = this.__listening.length == 0; + this.__listening.push(controller); + if (init) updateDisplays(this.__listening); + + } + + } + + ); + + function add(gui, object, property, params) { + + if (object[property] === undefined) { + throw new Error("Object " + object + " has no property \"" + property + "\""); + } + + var controller; + + if (params.color) { + + controller = new ColorController(object, property); + + } else { + + var factoryArgs = [object,property].concat(params.factoryArgs); + controller = controllerFactory.apply(gui, factoryArgs); + + } + + if (params.before instanceof Controller) { + params.before = params.before.__li; + } + + recallSavedValue(gui, controller); + + dom.addClass(controller.domElement, 'c'); + + var name = document.createElement('span'); + dom.addClass(name, 'property-name'); + name.innerHTML = controller.property; + + var container = document.createElement('div'); + container.appendChild(name); + container.appendChild(controller.domElement); + + var li = addRow(gui, container, params.before); + + dom.addClass(li, GUI.CLASS_CONTROLLER_ROW); + dom.addClass(li, typeof controller.getValue()); + + augmentController(gui, li, controller); + + gui.__controllers.push(controller); + + return controller; + + } + + /** + * Add a row to the end of the GUI or before another row. + * + * @param gui + * @param [dom] If specified, inserts the dom content in the new row + * @param [liBefore] If specified, places the new row before another row + */ + function addRow(gui, dom, liBefore) { + var li = document.createElement('li'); + if (dom) li.appendChild(dom); + if (liBefore) { + gui.__ul.insertBefore(li, params.before); + } else { + gui.__ul.appendChild(li); + } + gui.onResize(); + return li; + } + + function augmentController(gui, li, controller) { + + controller.__li = li; + controller.__gui = gui; + + common.extend(controller, { + + options: function(options) { + + if (arguments.length > 1) { + controller.remove(); + + return add( + gui, + controller.object, + controller.property, + { + before: controller.__li.nextElementSibling, + factoryArgs: [common.toArray(arguments)] + } + ); + + } + + if (common.isArray(options) || common.isObject(options)) { + controller.remove(); + + return add( + gui, + controller.object, + controller.property, + { + before: controller.__li.nextElementSibling, + factoryArgs: [options] + } + ); + + } + + }, + + name: function(v) { + controller.__li.firstElementChild.firstElementChild.innerHTML = v; + return controller; + }, + + listen: function() { + controller.__gui.listen(controller); + return controller; + }, + + remove: function() { + controller.__gui.remove(controller); + return controller; + } + + }); + + // All sliders should be accompanied by a box. + if (controller instanceof NumberControllerSlider) { + + var box = new NumberControllerBox(controller.object, controller.property, + { min: controller.__min, max: controller.__max, step: controller.__step }); + + common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) { + var pc = controller[method]; + var pb = box[method]; + controller[method] = box[method] = function() { + var args = Array.prototype.slice.call(arguments); + pc.apply(controller, args); + return pb.apply(box, args); + } + }); + + dom.addClass(li, 'has-slider'); + controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild); + + } + else if (controller instanceof NumberControllerBox) { + + var r = function(returned) { + + // Have we defined both boundaries? + if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) { + + // Well, then lets just replace this with a slider. + controller.remove(); + return add( + gui, + controller.object, + controller.property, + { + before: controller.__li.nextElementSibling, + factoryArgs: [controller.__min, controller.__max, controller.__step] + }); + + } + + return returned; + + }; + + controller.min = common.compose(r, controller.min); + controller.max = common.compose(r, controller.max); + + } + else if (controller instanceof BooleanController) { + + dom.bind(li, 'click', function() { + dom.fakeEvent(controller.__checkbox, 'click'); + }); + + dom.bind(controller.__checkbox, 'click', function(e) { + e.stopPropagation(); // Prevents double-toggle + }) + + } + else if (controller instanceof FunctionController) { + + dom.bind(li, 'click', function() { + dom.fakeEvent(controller.__button, 'click'); + }); + + dom.bind(li, 'mouseover', function() { + dom.addClass(controller.__button, 'hover'); + }); + + dom.bind(li, 'mouseout', function() { + dom.removeClass(controller.__button, 'hover'); + }); + + } + else if (controller instanceof ColorController) { + + dom.addClass(li, 'color'); + controller.updateDisplay = common.compose(function(r) { + li.style.borderLeftColor = controller.__color.toString(); + return r; + }, controller.updateDisplay); + + controller.updateDisplay(); + + } + + controller.setValue = common.compose(function(r) { + if (gui.getRoot().__preset_select && controller.isModified()) { + markPresetModified(gui.getRoot(), true); + } + return r; + }, controller.setValue); + + } + + function recallSavedValue(gui, controller) { + + // Find the topmost GUI, that's where remembered objects live. + var root = gui.getRoot(); + + // Does the object we're controlling match anything we've been told to + // remember? + var matched_index = root.__rememberedObjects.indexOf(controller.object); + + // Why yes, it does! + if (matched_index != -1) { + + // Let me fetch a map of controllers for thcommon.isObject. + var controller_map = + root.__rememberedObjectIndecesToControllers[matched_index]; + + // Ohp, I believe this is the first controller we've created for this + // object. Lets make the map fresh. + if (controller_map === undefined) { + controller_map = {}; + root.__rememberedObjectIndecesToControllers[matched_index] = + controller_map; + } + + // Keep track of this controller + controller_map[controller.property] = controller; + + // Okay, now have we saved any values for this controller? + if (root.load && root.load.remembered) { + + var preset_map = root.load.remembered; + + // Which preset are we trying to load? + var preset; + + if (preset_map[gui.preset]) { + + preset = preset_map[gui.preset]; + + } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) { + + // Uhh, you can have the default instead? + preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME]; + + } else { + + // Nada. + + return; + + } + + + // Did the loaded object remember thcommon.isObject? + if (preset[matched_index] && + + // Did we remember this particular property? + preset[matched_index][controller.property] !== undefined) { + + // We did remember something for this guy ... + var value = preset[matched_index][controller.property]; + + // And that's what it is. + controller.initialValue = value; + controller.setValue(value); + + } + + } + + } + + } + + function getLocalStorageHash(gui, key) { + // TODO how does this deal with multiple GUI's? + return document.location.href + '.' + key; + + } + + function addSaveMenu(gui) { + + var div = gui.__save_row = document.createElement('li'); + + dom.addClass(gui.domElement, 'has-save'); + + gui.__ul.insertBefore(div, gui.__ul.firstChild); + + dom.addClass(div, 'save-row'); + + var gears = document.createElement('span'); + gears.innerHTML = ' '; + dom.addClass(gears, 'button gears'); + + // TODO replace with FunctionController + var button = document.createElement('span'); + button.innerHTML = 'Save'; + dom.addClass(button, 'button'); + dom.addClass(button, 'save'); + + var button2 = document.createElement('span'); + button2.innerHTML = 'New'; + dom.addClass(button2, 'button'); + dom.addClass(button2, 'save-as'); + + var button3 = document.createElement('span'); + button3.innerHTML = 'Revert'; + dom.addClass(button3, 'button'); + dom.addClass(button3, 'revert'); + + var select = gui.__preset_select = document.createElement('select'); + + if (gui.load && gui.load.remembered) { + + common.each(gui.load.remembered, function(value, key) { + addPresetOption(gui, key, key == gui.preset); + }); + + } else { + addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false); + } + + dom.bind(select, 'change', function() { + + + for (var index = 0; index < gui.__preset_select.length; index++) { + gui.__preset_select[index].innerHTML = gui.__preset_select[index].value; + } + + gui.preset = this.value; + + }); + + div.appendChild(select); + div.appendChild(gears); + div.appendChild(button); + div.appendChild(button2); + div.appendChild(button3); + + if (SUPPORTS_LOCAL_STORAGE) { + + var saveLocally = document.getElementById('dg-save-locally'); + var explain = document.getElementById('dg-local-explain'); + + saveLocally.style.display = 'block'; + + var localStorageCheckBox = document.getElementById('dg-local-storage'); + + if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') { + localStorageCheckBox.setAttribute('checked', 'checked'); + } + + function showHideExplain() { + explain.style.display = gui.useLocalStorage ? 'block' : 'none'; + } + + showHideExplain(); + + // TODO: Use a boolean controller, fool! + dom.bind(localStorageCheckBox, 'change', function() { + gui.useLocalStorage = !gui.useLocalStorage; + showHideExplain(); + }); + + } + + var newConstructorTextArea = document.getElementById('dg-new-constructor'); + + dom.bind(newConstructorTextArea, 'keydown', function(e) { + if (e.metaKey && (e.which === 67 || e.keyCode == 67)) { + SAVE_DIALOGUE.hide(); + } + }); + + dom.bind(gears, 'click', function() { + newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2); + SAVE_DIALOGUE.show(); + newConstructorTextArea.focus(); + newConstructorTextArea.select(); + }); + + dom.bind(button, 'click', function() { + gui.save(); + }); + + dom.bind(button2, 'click', function() { + var presetName = prompt('Enter a new preset name.'); + if (presetName) gui.saveAs(presetName); + }); + + dom.bind(button3, 'click', function() { + gui.revert(); + }); + + // div.appendChild(button2); + + } + + function addResizeHandle(gui) { + + gui.__resize_handle = document.createElement('div'); + + common.extend(gui.__resize_handle.style, { + + width: '6px', + marginLeft: '-3px', + height: '200px', + cursor: 'ew-resize', + position: 'absolute' + // border: '1px solid blue' + + }); + + var pmouseX; + + dom.bind(gui.__resize_handle, 'mousedown', dragStart); + dom.bind(gui.__closeButton, 'mousedown', dragStart); + + gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild); + + function dragStart(e) { + + e.preventDefault(); + + pmouseX = e.clientX; + + dom.addClass(gui.__closeButton, GUI.CLASS_DRAG); + dom.bind(window, 'mousemove', drag); + dom.bind(window, 'mouseup', dragStop); + + return false; + + } + + function drag(e) { + + e.preventDefault(); + + gui.width += pmouseX - e.clientX; + gui.onResize(); + pmouseX = e.clientX; + + return false; + + } + + function dragStop() { + + dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG); + dom.unbind(window, 'mousemove', drag); + dom.unbind(window, 'mouseup', dragStop); + + } + + } + + function setWidth(gui, w) { + gui.domElement.style.width = w + 'px'; + // Auto placed save-rows are position fixed, so we have to + // set the width manually if we want it to bleed to the edge + if (gui.__save_row && gui.autoPlace) { + gui.__save_row.style.width = w + 'px'; + }if (gui.__closeButton) { + gui.__closeButton.style.width = w + 'px'; + } + } + + function getCurrentPreset(gui, useInitialValues) { + + var toReturn = {}; + + // For each object I'm remembering + common.each(gui.__rememberedObjects, function(val, index) { + + var saved_values = {}; + + // The controllers I've made for thcommon.isObject by property + var controller_map = + gui.__rememberedObjectIndecesToControllers[index]; + + // Remember each value for each property + common.each(controller_map, function(controller, property) { + saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue(); + }); + + // Save the values for thcommon.isObject + toReturn[index] = saved_values; + + }); + + return toReturn; + + } + + function addPresetOption(gui, name, setSelected) { + var opt = document.createElement('option'); + opt.innerHTML = name; + opt.value = name; + gui.__preset_select.appendChild(opt); + if (setSelected) { + gui.__preset_select.selectedIndex = gui.__preset_select.length - 1; + } + } + + function setPresetSelectIndex(gui) { + for (var index = 0; index < gui.__preset_select.length; index++) { + if (gui.__preset_select[index].value == gui.preset) { + gui.__preset_select.selectedIndex = index; + } + } + } + + function markPresetModified(gui, modified) { + var opt = gui.__preset_select[gui.__preset_select.selectedIndex]; + // console.log('mark', modified, opt); + if (modified) { + opt.innerHTML = opt.value + "*"; + } else { + opt.innerHTML = opt.value; + } + } + + function updateDisplays(controllerArray) { + + + if (controllerArray.length != 0) { + + requestAnimationFrame(function() { + updateDisplays(controllerArray); + }); + + } + + common.each(controllerArray, function(c) { + c.updateDisplay(); + }); + + } + + return GUI; + + })(dat.utils.css, + "
\n\n Here's the new load parameter for your GUI's constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI's constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n
", + ".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n", + dat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) { + + return function(object, property) { + + var initialValue = object[property]; + + // Providing options? + if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { + return new OptionController(object, property, arguments[2]); + } + + // Providing a map? + + if (common.isNumber(initialValue)) { + + if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) { + + // Has min and max. + return new NumberControllerSlider(object, property, arguments[2], arguments[3]); + + } else { + + return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] }); + + } + + } + + if (common.isString(initialValue)) { + return new StringController(object, property); + } + + if (common.isFunction(initialValue)) { + return new FunctionController(object, property, ''); + } + + if (common.isBoolean(initialValue)) { + return new BooleanController(object, property); + } + + } + + })(dat.controllers.OptionController, + dat.controllers.NumberControllerBox, + dat.controllers.NumberControllerSlider, + dat.controllers.StringController = (function (Controller, dom, common) { + + /** + * @class Provides a text input to alter the string property of an object. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var StringController = function(object, property) { + + StringController.superclass.call(this, object, property); + + var _this = this; + + this.__input = document.createElement('input'); + this.__input.setAttribute('type', 'text'); + + dom.bind(this.__input, 'keyup', onChange); + dom.bind(this.__input, 'change', onChange); + dom.bind(this.__input, 'blur', onBlur); + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { + this.blur(); + } + }); + + + function onChange() { + _this.setValue(_this.__input.value); + } + + function onBlur() { + if (_this.__onFinishChange) { + _this.__onFinishChange.call(_this, _this.getValue()); + } + } + + this.updateDisplay(); + + this.domElement.appendChild(this.__input); + + }; + + StringController.superclass = Controller; + + common.extend( + + StringController.prototype, + Controller.prototype, + + { + + updateDisplay: function() { + // Stops the caret from moving on account of: + // keyup -> setValue -> updateDisplay + if (!dom.isActive(this.__input)) { + this.__input.value = this.getValue(); + } + return StringController.superclass.prototype.updateDisplay.call(this); + } + + } + + ); + + return StringController; + + })(dat.controllers.Controller, + dat.dom.dom, + dat.utils.common), + dat.controllers.FunctionController, + dat.controllers.BooleanController, + dat.utils.common), + dat.controllers.Controller, + dat.controllers.BooleanController, + dat.controllers.FunctionController, + dat.controllers.NumberControllerBox, + dat.controllers.NumberControllerSlider, + dat.controllers.OptionController, + dat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) { + + var ColorController = function(object, property) { + + ColorController.superclass.call(this, object, property); + + this.__color = new Color(this.getValue()); + this.__temp = new Color(0); + + var _this = this; + + this.domElement = document.createElement('div'); + + dom.makeSelectable(this.domElement, false); + + this.__selector = document.createElement('div'); + this.__selector.className = 'selector'; + + this.__saturation_field = document.createElement('div'); + this.__saturation_field.className = 'saturation-field'; + + this.__field_knob = document.createElement('div'); + this.__field_knob.className = 'field-knob'; + this.__field_knob_border = '2px solid '; + + this.__hue_knob = document.createElement('div'); + this.__hue_knob.className = 'hue-knob'; + + this.__hue_field = document.createElement('div'); + this.__hue_field.className = 'hue-field'; + + this.__input = document.createElement('input'); + this.__input.type = 'text'; + this.__input_textShadow = '0 1px 1px '; + + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { // on enter + onBlur.call(this); + } + }); + + dom.bind(this.__input, 'blur', onBlur); + + dom.bind(this.__selector, 'mousedown', function(e) { + + dom + .addClass(this, 'drag') + .bind(window, 'mouseup', function(e) { + dom.removeClass(_this.__selector, 'drag'); + }); + + }); + + var value_field = document.createElement('div'); + + common.extend(this.__selector.style, { + width: '122px', + height: '102px', + padding: '3px', + backgroundColor: '#222', + boxShadow: '0px 1px 3px rgba(0,0,0,0.3)' + }); + + common.extend(this.__field_knob.style, { + position: 'absolute', + width: '12px', + height: '12px', + border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'), + boxShadow: '0px 1px 3px rgba(0,0,0,0.5)', + borderRadius: '12px', + zIndex: 1 + }); + + common.extend(this.__hue_knob.style, { + position: 'absolute', + width: '15px', + height: '2px', + borderRight: '4px solid #fff', + zIndex: 1 + }); + + common.extend(this.__saturation_field.style, { + width: '100px', + height: '100px', + border: '1px solid #555', + marginRight: '3px', + display: 'inline-block', + cursor: 'pointer' + }); + + common.extend(value_field.style, { + width: '100%', + height: '100%', + background: 'none' + }); + + linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000'); + + common.extend(this.__hue_field.style, { + width: '15px', + height: '100px', + display: 'inline-block', + border: '1px solid #555', + cursor: 'ns-resize' + }); + + hueGradient(this.__hue_field); + + common.extend(this.__input.style, { + outline: 'none', + // width: '120px', + textAlign: 'center', + // padding: '4px', + // marginBottom: '6px', + color: '#fff', + border: 0, + fontWeight: 'bold', + textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)' + }); + + dom.bind(this.__saturation_field, 'mousedown', fieldDown); + dom.bind(this.__field_knob, 'mousedown', fieldDown); + + dom.bind(this.__hue_field, 'mousedown', function(e) { + setH(e); + dom.bind(window, 'mousemove', setH); + dom.bind(window, 'mouseup', unbindH); + }); + + function fieldDown(e) { + setSV(e); + // document.body.style.cursor = 'none'; + dom.bind(window, 'mousemove', setSV); + dom.bind(window, 'mouseup', unbindSV); + } + + function unbindSV() { + dom.unbind(window, 'mousemove', setSV); + dom.unbind(window, 'mouseup', unbindSV); + // document.body.style.cursor = 'default'; + } + + function onBlur() { + var i = interpret(this.value); + if (i !== false) { + _this.__color.__state = i; + _this.setValue(_this.__color.toOriginal()); + } else { + this.value = _this.__color.toString(); + } + } + + function unbindH() { + dom.unbind(window, 'mousemove', setH); + dom.unbind(window, 'mouseup', unbindH); + } + + this.__saturation_field.appendChild(value_field); + this.__selector.appendChild(this.__field_knob); + this.__selector.appendChild(this.__saturation_field); + this.__selector.appendChild(this.__hue_field); + this.__hue_field.appendChild(this.__hue_knob); + + this.domElement.appendChild(this.__input); + this.domElement.appendChild(this.__selector); + + this.updateDisplay(); + + function setSV(e) { + + e.preventDefault(); + + var w = dom.getWidth(_this.__saturation_field); + var o = dom.getOffset(_this.__saturation_field); + var s = (e.clientX - o.left + document.body.scrollLeft) / w; + var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w; + + if (v > 1) v = 1; + else if (v < 0) v = 0; + + if (s > 1) s = 1; + else if (s < 0) s = 0; + + _this.__color.v = v; + _this.__color.s = s; + + _this.setValue(_this.__color.toOriginal()); + + + return false; + + } + + function setH(e) { + + e.preventDefault(); + + var s = dom.getHeight(_this.__hue_field); + var o = dom.getOffset(_this.__hue_field); + var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s; + + if (h > 1) h = 1; + else if (h < 0) h = 0; + + _this.__color.h = h * 360; + + _this.setValue(_this.__color.toOriginal()); + + return false; + + } + + }; + + ColorController.superclass = Controller; + + common.extend( + + ColorController.prototype, + Controller.prototype, + + { + + updateDisplay: function() { + + var i = interpret(this.getValue()); + + if (i !== false) { + + var mismatch = false; + + // Check for mismatch on the interpreted value. + + common.each(Color.COMPONENTS, function(component) { + if (!common.isUndefined(i[component]) && + !common.isUndefined(this.__color.__state[component]) && + i[component] !== this.__color.__state[component]) { + mismatch = true; + return {}; // break + } + }, this); + + // If nothing diverges, we keep our previous values + // for statefulness, otherwise we recalculate fresh + if (mismatch) { + common.extend(this.__color.__state, i); + } + + } + + common.extend(this.__temp.__state, this.__color.__state); + + this.__temp.a = 1; + + var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0; + var _flip = 255 - flip; + + common.extend(this.__field_knob.style, { + marginLeft: 100 * this.__color.s - 7 + 'px', + marginTop: 100 * (1 - this.__color.v) - 7 + 'px', + backgroundColor: this.__temp.toString(), + border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')' + }); + + this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px' + + this.__temp.s = 1; + this.__temp.v = 1; + + linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString()); + + common.extend(this.__input.style, { + backgroundColor: this.__input.value = this.__color.toString(), + color: 'rgb(' + flip + ',' + flip + ',' + flip +')', + textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)' + }); + + } + + } + + ); + + var vendors = ['-moz-','-o-','-webkit-','-ms-','']; + + function linearGradient(elem, x, a, b) { + elem.style.background = ''; + common.each(vendors, function(vendor) { + elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); '; + }); + } + + function hueGradient(elem) { + elem.style.background = ''; + elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);' + elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + } + + + return ColorController; + + })(dat.controllers.Controller, + dat.dom.dom, + dat.color.Color = (function (interpret, math, toString, common) { + + var Color = function() { + + this.__state = interpret.apply(this, arguments); + + if (this.__state === false) { + throw 'Failed to interpret color arguments'; + } + + this.__state.a = this.__state.a || 1; + + + }; + + Color.COMPONENTS = ['r','g','b','h','s','v','hex','a']; + + common.extend(Color.prototype, { + + toString: function() { + return toString(this); + }, + + toOriginal: function() { + return this.__state.conversion.write(this); + } + + }); + + defineRGBComponent(Color.prototype, 'r', 2); + defineRGBComponent(Color.prototype, 'g', 1); + defineRGBComponent(Color.prototype, 'b', 0); + + defineHSVComponent(Color.prototype, 'h'); + defineHSVComponent(Color.prototype, 's'); + defineHSVComponent(Color.prototype, 'v'); + + Object.defineProperty(Color.prototype, 'a', { + + get: function() { + return this.__state.a; + }, + + set: function(v) { + this.__state.a = v; + } + + }); + + Object.defineProperty(Color.prototype, 'hex', { + + get: function() { + + if (!this.__state.space !== 'HEX') { + this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b); + } + + return this.__state.hex; + + }, + + set: function(v) { + + this.__state.space = 'HEX'; + this.__state.hex = v; + + } + + }); + + function defineRGBComponent(target, component, componentHexIndex) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'RGB') { + return this.__state[component]; + } + + recalculateRGB(this, component, componentHexIndex); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'RGB') { + recalculateRGB(this, component, componentHexIndex); + this.__state.space = 'RGB'; + } + + this.__state[component] = v; + + } + + }); + + } + + function defineHSVComponent(target, component) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'HSV') + return this.__state[component]; + + recalculateHSV(this); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'HSV') { + recalculateHSV(this); + this.__state.space = 'HSV'; + } + + this.__state[component] = v; + + } + + }); + + } + + function recalculateRGB(color, component, componentHexIndex) { + + if (color.__state.space === 'HEX') { + + color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex); + + } else if (color.__state.space === 'HSV') { + + common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v)); + + } else { + + throw 'Corrupted color state'; + + } + + } + + function recalculateHSV(color) { + + var result = math.rgb_to_hsv(color.r, color.g, color.b); + + common.extend(color.__state, + { + s: result.s, + v: result.v + } + ); + + if (!common.isNaN(result.h)) { + color.__state.h = result.h; + } else if (common.isUndefined(color.__state.h)) { + color.__state.h = 0; + } + + } + + return Color; + + })(dat.color.interpret, + dat.color.math = (function () { + + var tmpComponent; + + return { + + hsv_to_rgb: function(h, s, v) { + + var hi = Math.floor(h / 60) % 6; + + var f = h / 60 - Math.floor(h / 60); + var p = v * (1.0 - s); + var q = v * (1.0 - (f * s)); + var t = v * (1.0 - ((1.0 - f) * s)); + var c = [ + [v, t, p], + [q, v, p], + [p, v, t], + [p, q, v], + [t, p, v], + [v, p, q] + ][hi]; + + return { + r: c[0] * 255, + g: c[1] * 255, + b: c[2] * 255 + }; + + }, + + rgb_to_hsv: function(r, g, b) { + + var min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s; + + if (max != 0) { + s = delta / max; + } else { + return { + h: NaN, + s: 0, + v: 0 + }; + } + + if (r == max) { + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + h /= 6; + if (h < 0) { + h += 1; + } + + return { + h: h * 360, + s: s, + v: max / 255 + }; + }, + + rgb_to_hex: function(r, g, b) { + var hex = this.hex_with_component(0, 2, r); + hex = this.hex_with_component(hex, 1, g); + hex = this.hex_with_component(hex, 0, b); + return hex; + }, + + component_from_hex: function(hex, componentIndex) { + return (hex >> (componentIndex * 8)) & 0xFF; + }, + + hex_with_component: function(hex, componentIndex, value) { + return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); + } + + } + + })(), + dat.color.toString, + dat.utils.common), + dat.color.interpret, + dat.utils.common), + dat.utils.requestAnimationFrame = (function () { + + /** + * requirejs version of Paul Irish's RequestAnimationFrame + * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + */ + + return window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback, element) { + + window.setTimeout(callback, 1000 / 60); + + }; + })(), + dat.dom.CenteredDiv = (function (dom, common) { + + + var CenteredDiv = function() { + + this.backgroundElement = document.createElement('div'); + common.extend(this.backgroundElement.style, { + backgroundColor: 'rgba(0,0,0,0.8)', + top: 0, + left: 0, + display: 'none', + zIndex: '1000', + opacity: 0, + WebkitTransition: 'opacity 0.2s linear' + }); + + dom.makeFullscreen(this.backgroundElement); + this.backgroundElement.style.position = 'fixed'; + + this.domElement = document.createElement('div'); + common.extend(this.domElement.style, { + position: 'fixed', + display: 'none', + zIndex: '1001', + opacity: 0, + WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear' + }); + + + document.body.appendChild(this.backgroundElement); + document.body.appendChild(this.domElement); + + var _this = this; + dom.bind(this.backgroundElement, 'click', function() { + _this.hide(); + }); + + + }; + + CenteredDiv.prototype.show = function() { + + var _this = this; + + + + this.backgroundElement.style.display = 'block'; + + this.domElement.style.display = 'block'; + this.domElement.style.opacity = 0; + // this.domElement.style.top = '52%'; + this.domElement.style.webkitTransform = 'scale(1.1)'; + + this.layout(); + + common.defer(function() { + _this.backgroundElement.style.opacity = 1; + _this.domElement.style.opacity = 1; + _this.domElement.style.webkitTransform = 'scale(1)'; + }); + + }; + + CenteredDiv.prototype.hide = function() { + + var _this = this; + + var hide = function() { + + _this.domElement.style.display = 'none'; + _this.backgroundElement.style.display = 'none'; + + dom.unbind(_this.domElement, 'webkitTransitionEnd', hide); + dom.unbind(_this.domElement, 'transitionend', hide); + dom.unbind(_this.domElement, 'oTransitionEnd', hide); + + }; + + dom.bind(this.domElement, 'webkitTransitionEnd', hide); + dom.bind(this.domElement, 'transitionend', hide); + dom.bind(this.domElement, 'oTransitionEnd', hide); + + this.backgroundElement.style.opacity = 0; + // this.domElement.style.top = '48%'; + this.domElement.style.opacity = 0; + this.domElement.style.webkitTransform = 'scale(1.1)'; + + }; + + CenteredDiv.prototype.layout = function() { + this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px'; + this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px'; + }; + + function lockScroll(e) { + console.log(e); + } + + return CenteredDiv; + + })(dat.dom.dom, + dat.utils.common), + dat.dom.dom, + dat.utils.common); + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + /** + * dat-gui JavaScript Controller Library + * http://code.google.com/p/dat-gui + * + * Copyright 2011 Data Arts Team, Google Creative Lab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + /** @namespace */ + var dat = module.exports = dat || {}; + + /** @namespace */ + dat.color = dat.color || {}; + + /** @namespace */ + dat.utils = dat.utils || {}; + + dat.utils.common = (function () { + + var ARR_EACH = Array.prototype.forEach; + var ARR_SLICE = Array.prototype.slice; + + /** + * Band-aid methods for things that should be a lot easier in JavaScript. + * Implementation and structure inspired by underscore.js + * http://documentcloud.github.com/underscore/ + */ + + return { + + BREAK: {}, + + extend: function(target) { + + this.each(ARR_SLICE.call(arguments, 1), function(obj) { + + for (var key in obj) + if (!this.isUndefined(obj[key])) + target[key] = obj[key]; + + }, this); + + return target; + + }, + + defaults: function(target) { + + this.each(ARR_SLICE.call(arguments, 1), function(obj) { + + for (var key in obj) + if (this.isUndefined(target[key])) + target[key] = obj[key]; + + }, this); + + return target; + + }, + + compose: function() { + var toCall = ARR_SLICE.call(arguments); + return function() { + var args = ARR_SLICE.call(arguments); + for (var i = toCall.length -1; i >= 0; i--) { + args = [toCall[i].apply(this, args)]; + } + return args[0]; + } + }, + + each: function(obj, itr, scope) { + + + if (ARR_EACH && obj.forEach === ARR_EACH) { + + obj.forEach(itr, scope); + + } else if (obj.length === obj.length + 0) { // Is number but not NaN + + for (var key = 0, l = obj.length; key < l; key++) + if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) + return; + + } else { + + for (var key in obj) + if (itr.call(scope, obj[key], key) === this.BREAK) + return; + + } + + }, + + defer: function(fnc) { + setTimeout(fnc, 0); + }, + + toArray: function(obj) { + if (obj.toArray) return obj.toArray(); + return ARR_SLICE.call(obj); + }, + + isUndefined: function(obj) { + return obj === undefined; + }, + + isNull: function(obj) { + return obj === null; + }, + + isNaN: function(obj) { + return obj !== obj; + }, + + isArray: Array.isArray || function(obj) { + return obj.constructor === Array; + }, + + isObject: function(obj) { + return obj === Object(obj); + }, + + isNumber: function(obj) { + return obj === obj+0; + }, + + isString: function(obj) { + return obj === obj+''; + }, + + isBoolean: function(obj) { + return obj === false || obj === true; + }, + + isFunction: function(obj) { + return Object.prototype.toString.call(obj) === '[object Function]'; + } + + }; + + })(); + + + dat.color.toString = (function (common) { + + return function(color) { + + if (color.a == 1 || common.isUndefined(color.a)) { + + var s = color.hex.toString(16); + while (s.length < 6) { + s = '0' + s; + } + + return '#' + s; + + } else { + + return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')'; + + } + + } + + })(dat.utils.common); + + + dat.Color = dat.color.Color = (function (interpret, math, toString, common) { + + var Color = function() { + + this.__state = interpret.apply(this, arguments); + + if (this.__state === false) { + throw 'Failed to interpret color arguments'; + } + + this.__state.a = this.__state.a || 1; + + + }; + + Color.COMPONENTS = ['r','g','b','h','s','v','hex','a']; + + common.extend(Color.prototype, { + + toString: function() { + return toString(this); + }, + + toOriginal: function() { + return this.__state.conversion.write(this); + } + + }); + + defineRGBComponent(Color.prototype, 'r', 2); + defineRGBComponent(Color.prototype, 'g', 1); + defineRGBComponent(Color.prototype, 'b', 0); + + defineHSVComponent(Color.prototype, 'h'); + defineHSVComponent(Color.prototype, 's'); + defineHSVComponent(Color.prototype, 'v'); + + Object.defineProperty(Color.prototype, 'a', { + + get: function() { + return this.__state.a; + }, + + set: function(v) { + this.__state.a = v; + } + + }); + + Object.defineProperty(Color.prototype, 'hex', { + + get: function() { + + if (!this.__state.space !== 'HEX') { + this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b); + } + + return this.__state.hex; + + }, + + set: function(v) { + + this.__state.space = 'HEX'; + this.__state.hex = v; + + } + + }); + + function defineRGBComponent(target, component, componentHexIndex) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'RGB') { + return this.__state[component]; + } + + recalculateRGB(this, component, componentHexIndex); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'RGB') { + recalculateRGB(this, component, componentHexIndex); + this.__state.space = 'RGB'; + } + + this.__state[component] = v; + + } + + }); + + } + + function defineHSVComponent(target, component) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'HSV') + return this.__state[component]; + + recalculateHSV(this); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'HSV') { + recalculateHSV(this); + this.__state.space = 'HSV'; + } + + this.__state[component] = v; + + } + + }); + + } + + function recalculateRGB(color, component, componentHexIndex) { + + if (color.__state.space === 'HEX') { + + color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex); + + } else if (color.__state.space === 'HSV') { + + common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v)); + + } else { + + throw 'Corrupted color state'; + + } + + } + + function recalculateHSV(color) { + + var result = math.rgb_to_hsv(color.r, color.g, color.b); + + common.extend(color.__state, + { + s: result.s, + v: result.v + } + ); + + if (!common.isNaN(result.h)) { + color.__state.h = result.h; + } else if (common.isUndefined(color.__state.h)) { + color.__state.h = 0; + } + + } + + return Color; + + })(dat.color.interpret = (function (toString, common) { + + var result, toReturn; + + var interpret = function() { + + toReturn = false; + + var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0]; + + common.each(INTERPRETATIONS, function(family) { + + if (family.litmus(original)) { + + common.each(family.conversions, function(conversion, conversionName) { + + result = conversion.read(original); + + if (toReturn === false && result !== false) { + toReturn = result; + result.conversionName = conversionName; + result.conversion = conversion; + return common.BREAK; + + } + + }); + + return common.BREAK; + + } + + }); + + return toReturn; + + }; + + var INTERPRETATIONS = [ + + // Strings + { + + litmus: common.isString, + + conversions: { + + THREE_CHAR_HEX: { + + read: function(original) { + + var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i); + if (test === null) return false; + + return { + space: 'HEX', + hex: parseInt( + '0x' + + test[1].toString() + test[1].toString() + + test[2].toString() + test[2].toString() + + test[3].toString() + test[3].toString()) + }; + + }, + + write: toString + + }, + + SIX_CHAR_HEX: { + + read: function(original) { + + var test = original.match(/^#([A-F0-9]{6})$/i); + if (test === null) return false; + + return { + space: 'HEX', + hex: parseInt('0x' + test[1].toString()) + }; + + }, + + write: toString + + }, + + CSS_RGB: { + + read: function(original) { + + var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); + if (test === null) return false; + + return { + space: 'RGB', + r: parseFloat(test[1]), + g: parseFloat(test[2]), + b: parseFloat(test[3]) + }; + + }, + + write: toString + + }, + + CSS_RGBA: { + + read: function(original) { + + var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/); + if (test === null) return false; + + return { + space: 'RGB', + r: parseFloat(test[1]), + g: parseFloat(test[2]), + b: parseFloat(test[3]), + a: parseFloat(test[4]) + }; + + }, + + write: toString + + } + + } + + }, + + // Numbers + { + + litmus: common.isNumber, + + conversions: { + + HEX: { + read: function(original) { + return { + space: 'HEX', + hex: original, + conversionName: 'HEX' + } + }, + + write: function(color) { + return color.hex; + } + } + + } + + }, + + // Arrays + { + + litmus: common.isArray, + + conversions: { + + RGB_ARRAY: { + read: function(original) { + if (original.length != 3) return false; + return { + space: 'RGB', + r: original[0], + g: original[1], + b: original[2] + }; + }, + + write: function(color) { + return [color.r, color.g, color.b]; + } + + }, + + RGBA_ARRAY: { + read: function(original) { + if (original.length != 4) return false; + return { + space: 'RGB', + r: original[0], + g: original[1], + b: original[2], + a: original[3] + }; + }, + + write: function(color) { + return [color.r, color.g, color.b, color.a]; + } + + } + + } + + }, + + // Objects + { + + litmus: common.isObject, + + conversions: { + + RGBA_OBJ: { + read: function(original) { + if (common.isNumber(original.r) && + common.isNumber(original.g) && + common.isNumber(original.b) && + common.isNumber(original.a)) { + return { + space: 'RGB', + r: original.r, + g: original.g, + b: original.b, + a: original.a + } + } + return false; + }, + + write: function(color) { + return { + r: color.r, + g: color.g, + b: color.b, + a: color.a + } + } + }, + + RGB_OBJ: { + read: function(original) { + if (common.isNumber(original.r) && + common.isNumber(original.g) && + common.isNumber(original.b)) { + return { + space: 'RGB', + r: original.r, + g: original.g, + b: original.b + } + } + return false; + }, + + write: function(color) { + return { + r: color.r, + g: color.g, + b: color.b + } + } + }, + + HSVA_OBJ: { + read: function(original) { + if (common.isNumber(original.h) && + common.isNumber(original.s) && + common.isNumber(original.v) && + common.isNumber(original.a)) { + return { + space: 'HSV', + h: original.h, + s: original.s, + v: original.v, + a: original.a + } + } + return false; + }, + + write: function(color) { + return { + h: color.h, + s: color.s, + v: color.v, + a: color.a + } + } + }, + + HSV_OBJ: { + read: function(original) { + if (common.isNumber(original.h) && + common.isNumber(original.s) && + common.isNumber(original.v)) { + return { + space: 'HSV', + h: original.h, + s: original.s, + v: original.v + } + } + return false; + }, + + write: function(color) { + return { + h: color.h, + s: color.s, + v: color.v + } + } + + } + + } + + } + + + ]; + + return interpret; + + + })(dat.color.toString, + dat.utils.common), + dat.color.math = (function () { + + var tmpComponent; + + return { + + hsv_to_rgb: function(h, s, v) { + + var hi = Math.floor(h / 60) % 6; + + var f = h / 60 - Math.floor(h / 60); + var p = v * (1.0 - s); + var q = v * (1.0 - (f * s)); + var t = v * (1.0 - ((1.0 - f) * s)); + var c = [ + [v, t, p], + [q, v, p], + [p, v, t], + [p, q, v], + [t, p, v], + [v, p, q] + ][hi]; + + return { + r: c[0] * 255, + g: c[1] * 255, + b: c[2] * 255 + }; + + }, + + rgb_to_hsv: function(r, g, b) { + + var min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s; + + if (max != 0) { + s = delta / max; + } else { + return { + h: NaN, + s: 0, + v: 0 + }; + } + + if (r == max) { + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + h /= 6; + if (h < 0) { + h += 1; + } + + return { + h: h * 360, + s: s, + v: max / 255 + }; + }, + + rgb_to_hex: function(r, g, b) { + var hex = this.hex_with_component(0, 2, r); + hex = this.hex_with_component(hex, 1, g); + hex = this.hex_with_component(hex, 0, b); + return hex; + }, + + component_from_hex: function(hex, componentIndex) { + return (hex >> (componentIndex * 8)) & 0xFF; + }, + + hex_with_component: function(hex, componentIndex, value) { + return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); + } + + } + + })(), + dat.color.toString, + dat.utils.common); + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + module.exports = function( THREE ) { + /** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + */ + + // This set of controls performs orbiting, dollying (zooming), and panning. + // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). + // + // Orbit - left mouse / touch: one finger move + // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish + // Pan - right mouse, or arrow keys / touch: three finter swipe + + function OrbitControls( object, domElement ) { + + this.object = object; + + this.domElement = ( domElement !== undefined ) ? domElement : document; + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + + // How far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; + + // Set to false to disable panning + this.enablePan = true; + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // Set to false to disable use of the keys + this.enableKeys = true; + + // The four arrow keys + this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; + + // Mouse buttons + this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; + + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // + // public methods + // + + this.getPolarAngle = function () { + + return spherical.phi; + + }; + + this.getAzimuthalAngle = function () { + + return spherical.theta; + + }; + + this.reset = function () { + + scope.target.copy( scope.target0 ); + scope.object.position.copy( scope.position0 ); + scope.object.zoom = scope.zoom0; + + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + scope.update(); + + state = STATE.NONE; + + }; + + // this method is exposed, but perhaps it would be better if we can make it private... + this.update = function() { + + var offset = new THREE.Vector3(); + + // so camera.up is the orbit axis + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + return function update () { + + var position = scope.object.position; + + offset.copy( position ).sub( scope.target ); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + + // angle from z-axis around y-axis + spherical.setFromVector3( offset ); + + if ( scope.autoRotate && state === STATE.NONE ) { + + rotateLeft( getAutoRotationAngle() ); + + } + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); + + // restrict phi to be between desired limits + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); + + spherical.makeSafe(); + + + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); + + // move target to panned location + scope.target.add( panOffset ); + + offset.setFromSpherical( spherical ); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); + + position.copy( scope.target ).add( offset ); + + scope.object.lookAt( scope.target ); + + if ( scope.enableDamping === true ) { + + sphericalDelta.theta *= ( 1 - scope.dampingFactor ); + sphericalDelta.phi *= ( 1 - scope.dampingFactor ); + + } else { + + sphericalDelta.set( 0, 0, 0 ); + + } + + scale = 1; + panOffset.set( 0, 0, 0 ); + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + + if ( zoomChanged || + lastPosition.distanceToSquared( scope.object.position ) > EPS || + 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { + + scope.dispatchEvent( changeEvent ); + + lastPosition.copy( scope.object.position ); + lastQuaternion.copy( scope.object.quaternion ); + zoomChanged = false; + + return true; + + } + + return false; + + }; + + }(); + + this.dispose = function() { + + scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); + scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + window.removeEventListener( 'keydown', onKeyDown, false ); + + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + + }; + + // + // internals + // + + var scope = this; + + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; + + var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; + + var state = STATE.NONE; + + var EPS = 0.000001; + + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); + + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + function getAutoRotationAngle() { + + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + + } + + function getZoomScale() { + + return Math.pow( 0.95, scope.zoomSpeed ); + + } + + function rotateLeft( angle ) { + + sphericalDelta.theta -= angle; + + } + + function rotateUp( angle ) { + + sphericalDelta.phi -= angle; + + } + + var panLeft = function() { + + var v = new THREE.Vector3(); + + return function panLeft( distance, objectMatrix ) { + + v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix + v.multiplyScalar( - distance ); + + panOffset.add( v ); + + }; + + }(); + + var panUp = function() { + + var v = new THREE.Vector3(); + + return function panUp( distance, objectMatrix ) { + + v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix + v.multiplyScalar( distance ); + + panOffset.add( v ); + + }; + + }(); + + // deltaX and deltaY are in pixels; right and down are positive + var pan = function() { + + var offset = new THREE.Vector3(); + + return function pan ( deltaX, deltaY ) { + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + // perspective + var position = scope.object.position; + offset.copy( position ).sub( scope.target ); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + + // we actually don't use screenWidth, since perspective camera is fixed to screen height + panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); + panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + // orthographic + panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); + panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); + + } else { + + // camera neither orthographic nor perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + scope.enablePan = false; + + } + + }; + + }(); + + function dollyIn( dollyScale ) { + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + function dollyOut( dollyScale ) { + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + // + // event callbacks - update the object state + // + + function handleMouseDownRotate( event ) { + + //console.log( 'handleMouseDownRotate' ); + + rotateStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownDolly( event ) { + + //console.log( 'handleMouseDownDolly' ); + + dollyStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownPan( event ) { + + //console.log( 'handleMouseDownPan' ); + + panStart.set( event.clientX, event.clientY ); + + } + + function handleMouseMoveRotate( event ) { + + //console.log( 'handleMouseMoveRotate' ); + + rotateEnd.set( event.clientX, event.clientY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + // rotating across whole screen goes 360 degrees around + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + + // rotating up and down along whole screen attempts to go 360, but limited to 180 + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleMouseMoveDolly( event ) { + + //console.log( 'handleMouseMoveDolly' ); + + dollyEnd.set( event.clientX, event.clientY ); + + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyIn( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyOut( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleMouseMovePan( event ) { + + //console.log( 'handleMouseMovePan' ); + + panEnd.set( event.clientX, event.clientY ); + + panDelta.subVectors( panEnd, panStart ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleMouseUp( event ) { + + //console.log( 'handleMouseUp' ); + + } + + function handleMouseWheel( event ) { + + //console.log( 'handleMouseWheel' ); + + if ( event.deltaY < 0 ) { + + dollyOut( getZoomScale() ); + + } else if ( event.deltaY > 0 ) { + + dollyIn( getZoomScale() ); + + } + + scope.update(); + + } + + function handleKeyDown( event ) { + + //console.log( 'handleKeyDown' ); + + switch ( event.keyCode ) { + + case scope.keys.UP: + pan( 0, scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.BOTTOM: + pan( 0, - scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.LEFT: + pan( scope.keyPanSpeed, 0 ); + scope.update(); + break; + + case scope.keys.RIGHT: + pan( - scope.keyPanSpeed, 0 ); + scope.update(); + break; + + } + + } + + function handleTouchStartRotate( event ) { + + //console.log( 'handleTouchStartRotate' ); + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchStartDolly( event ) { + + //console.log( 'handleTouchStartDolly' ); + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyStart.set( 0, distance ); + + } + + function handleTouchStartPan( event ) { + + //console.log( 'handleTouchStartPan' ); + + panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchMoveRotate( event ) { + + //console.log( 'handleTouchMoveRotate' ); + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + // rotating across whole screen goes 360 degrees around + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + + // rotating up and down along whole screen attempts to go 360, but limited to 180 + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleTouchMoveDolly( event ) { + + //console.log( 'handleTouchMoveDolly' ); + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyEnd.set( 0, distance ); + + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyOut( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyIn( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleTouchMovePan( event ) { + + //console.log( 'handleTouchMovePan' ); + + panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + panDelta.subVectors( panEnd, panStart ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleTouchEnd( event ) { + + //console.log( 'handleTouchEnd' ); + + } + + // + // event handlers - FSM: listen for events and reset state + // + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + if ( event.button === scope.mouseButtons.ORBIT ) { + + if ( scope.enableRotate === false ) return; + + handleMouseDownRotate( event ); + + state = STATE.ROTATE; + + } else if ( event.button === scope.mouseButtons.ZOOM ) { + + if ( scope.enableZoom === false ) return; + + handleMouseDownDolly( event ); + + state = STATE.DOLLY; + + } else if ( event.button === scope.mouseButtons.PAN ) { + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + } + + if ( state !== STATE.NONE ) { + + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( startEvent ); + + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + if ( state === STATE.ROTATE ) { + + if ( scope.enableRotate === false ) return; + + handleMouseMoveRotate( event ); + + } else if ( state === STATE.DOLLY ) { + + if ( scope.enableZoom === false ) return; + + handleMouseMoveDolly( event ); + + } else if ( state === STATE.PAN ) { + + if ( scope.enablePan === false ) return; + + handleMouseMovePan( event ); + + } + + } + + function onMouseUp( event ) { + + if ( scope.enabled === false ) return; + + handleMouseUp( event ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; + + event.preventDefault(); + event.stopPropagation(); + + handleMouseWheel( event ); + + scope.dispatchEvent( startEvent ); // not sure why these are here... + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; + + handleKeyDown( event ); + + } + + function onTouchStart( event ) { + + if ( scope.enabled === false ) return; + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + + handleTouchStartRotate( event ); + + state = STATE.TOUCH_ROTATE; + + break; + + case 2: // two-fingered touch: dolly + + if ( scope.enableZoom === false ) return; + + handleTouchStartDolly( event ); + + state = STATE.TOUCH_DOLLY; + + break; + + case 3: // three-fingered touch: pan + + if ( scope.enablePan === false ) return; + + handleTouchStartPan( event ); + + state = STATE.TOUCH_PAN; + + break; + + default: + + state = STATE.NONE; + + } + + if ( state !== STATE.NONE ) { + + scope.dispatchEvent( startEvent ); + + } + + } + + function onTouchMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?... + + handleTouchMoveRotate( event ); + + break; + + case 2: // two-fingered touch: dolly + + if ( scope.enableZoom === false ) return; + if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?... + + handleTouchMoveDolly( event ); + + break; + + case 3: // three-fingered touch: pan + + if ( scope.enablePan === false ) return; + if ( state !== STATE.TOUCH_PAN ) return; // is this needed?... + + handleTouchMovePan( event ); + + break; + + default: + + state = STATE.NONE; + + } + + } + + function onTouchEnd( event ) { + + if ( scope.enabled === false ) return; + + handleTouchEnd( event ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onContextMenu( event ) { + + event.preventDefault(); + + } + + // + + scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); + + scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + + this.update(); + + }; + + OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); + OrbitControls.prototype.constructor = OrbitControls; + + Object.defineProperties( OrbitControls.prototype, { + + center: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); + return this.target; + + } + + }, + + // backward compatibility + + noZoom: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + return ! this.enableZoom; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + this.enableZoom = ! value; + + } + + }, + + noRotate: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + return ! this.enableRotate; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + this.enableRotate = ! value; + + } + + }, + + noPan: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + return ! this.enablePan; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + this.enablePan = ! value; + + } + + }, + + noKeys: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + return ! this.enableKeys; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + this.enableKeys = ! value; + + } + + }, + + staticMoving : { + + get: function () { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + return ! this.enableDamping; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + this.enableDamping = ! value; + + } + + }, + + dynamicDampingFactor : { + + get: function () { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + return this.dampingFactor; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + this.dampingFactor = value; + + } + + } + + } ); + + return OrbitControls; + }; + + +/***/ }, +/* 10 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + ///////////////////////////////////// + // Marching cubes lookup tables + ///////////////////////////////////// + + // Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/ + // These tables are straight from Paul Bourke's page: + // http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/ + // who in turn got them from Cory Gene Bloyd. + + var EDGE_TABLE = new Int32Array([0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190, 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0]); + + var TRI_TABLE = new Int32Array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1, 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1, 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1, 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1, 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1, 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1, 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1, 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1, 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1, 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1, 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1, 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1, 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1, 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1, 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1, 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1, 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1, 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1, 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1, 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1, 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1, 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1, 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1, 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1, 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1, 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1, 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1, 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1, 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1, 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1, 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1, 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1, 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1, 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1, 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1, 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1, 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1, 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1, 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1, 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1, 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1, 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1, 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1, 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1, 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1, 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1, 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1, 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1, 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1, 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1, 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1, 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1, 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1, 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1, 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1, 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1, 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1, 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1, 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1, 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1, 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1, 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1, 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1, 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1, 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1, 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1, 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1, 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1, 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1, 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1, 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1, 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1, 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1, 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1, 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1, 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1, 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1, 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1, 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1, 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1, 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1, 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1, 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1, 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1, 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1, 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1, 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1, 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1, 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1, 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1, 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1, 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1, 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1, 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1, 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1, 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1, 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1, 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1, 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1, 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1, 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1, 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1, 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1, 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1, 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1, 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1, 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1, 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1, 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1, 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1, 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1, 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1, 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1, 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1, 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1, 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1, 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1, 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1, 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1, 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1, 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1, 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1, 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1, 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1, 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1, 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1, 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1, 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1, 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1, 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1, 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1, 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1, 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1, 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1, 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1, 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1, 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1, 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1, 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1, 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1, 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1, 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1, 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1, 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1, 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1, 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1, 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1, 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1, 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1, 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1, 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1, 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1, 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 8, -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, -1, -1]); + + exports.default = { + EDGE_TABLE: EDGE_TABLE, + TRI_TABLE: TRI_TABLE + }; + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _textures = __webpack_require__(1); + + var _metaball = __webpack_require__(12); + + var _metaball2 = _interopRequireDefault(_metaball); + + var _inspect_point = __webpack_require__(13); + + var _inspect_point2 = _interopRequireDefault(_inspect_point); + + var _marching_cube_LUT = __webpack_require__(10); + + var _marching_cube_LUT2 = _interopRequireDefault(_marching_cube_LUT); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var THREE = __webpack_require__(2); + + var VISUAL_DEBUG = true; + var episolon = 0.1; + var balls = []; + + var options = { lightColor: '#ffffff', lightIntensity: 1, ambient: '#111111', texture: null }; + + // lava + var l_mat = { + uniforms: { + texture: { type: "t", value: null }, + u_ambient: { type: 'v3', value: new THREE.Color(options.ambient) }, + u_lightCol: { type: 'v3', value: new THREE.Color(options.lightColor) }, + u_lightIntensity: { type: 'f', value: options.lightIntensity } + }, + vertexShader: __webpack_require__(14), + fragmentShader: __webpack_require__(15) + }; + + var LAVA_MAT = new THREE.ShaderMaterial(l_mat); + var LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 }); + var LAMBERT_GREEN = new THREE.MeshBasicMaterial({ color: 0x00ee00, transparent: true, opacity: 0.5 }); + var WIREFRAME_MAT = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 10 }); + + // This function samples a point from the metaball's density function + // Implement a function that returns the value of the all metaballs influence to a given point. + // Please follow the resources given in the write-up for details. + function sample(point) { + var isovalue = 0.0; + for (var i = 0; i < balls.length; i++) { + var r = balls[i].radius; + var d = point.distanceTo(balls[i].pos); + //isovalue += (r * r / (d * d)) * balls[i].neg; + isovalue += r * r / (d * d); + } + return isovalue; + } + + var MarchingCubes = function () { + function MarchingCubes(App) { + _classCallCheck(this, MarchingCubes); + + this.init(App); + } + + _createClass(MarchingCubes, [{ + key: 'init', + value: function init(App) { + this.isPaused = false; + VISUAL_DEBUG = App.config.visualDebug; + + // Initializing member variables. + // Additional variables are used for fast computation. + this.origin = new THREE.Vector3(0); + + this.isolevel = App.config.isolevel; + this.minRadius = App.config.minRadius; + this.maxRadius = App.config.maxRadius; + + this.gridCellWidth = App.config.gridCellWidth; + this.gridCellHeight = App.config.gridCellHeight; + this.gridCellDepth = App.config.gridCellDepth; + this.halfCellWidth = App.config.gridCellWidth / 2.0; + this.halfCellHeight = App.config.gridCellHeight / 2.0; + this.halfCellDepth = App.config.gridCellDepth / 2.0; + this.gridWidth = App.config.gridWidth; + this.gridHeight = App.config.gridHeight; + this.gridDepth = App.config.gridDepth; + + this.res = App.config.gridRes; + this.res2 = App.config.gridRes * App.config.gridRes; + this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes; + + this.maxSpeedX = App.config.maxSpeedX; + this.maxSpeedY = App.config.maxSpeedY; + this.maxSpeedZ = App.config.maxSpeedZ; + this.numMetaballs = App.config.numMetaballs; + + this.camera = App.camera; + this.scene = App.scene; + + this.voxels = []; + //this.labels = []; + this.balls = balls; + + this.showSpheres = true; + this.showGrid = true; + + _textures.silverTexture.then(function (texture) { + l_mat.uniforms.texture.value = texture; + }); + + if (App.config.material) { + this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d }); + } else { + this.material = App.config.material; + } + + this.setupCells(); + this.setupMetaballs(); + this.makeMesh(); + } + }, { + key: 'i1toi3', + + + // Convert from 1D index to 3D indices + value: function i1toi3(i1) { + + // [i % w, i % (h * w)) / w, i / (h * w)] + + // @note: ~~ is a fast substitute for Math.floor() + return [i1 % this.res, ~~(i1 % this.res2 / this.res), ~~(i1 / this.res2)]; + } + }, { + key: 'i3toi1', + + + // Convert from 3D indices to 1 1D + value: function i3toi1(i3x, i3y, i3z) { + + // [x + y * w + z * w * h] + + return i3x + i3y * this.res + i3z * this.res2; + } + }, { + key: 'i3toPos', + + + // Convert from 3D indices to 3D positions + value: function i3toPos(i3) { + + return new THREE.Vector3(i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth, i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight, i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth); + } + }, { + key: 'setupCells', + value: function setupCells() { + + // Allocate voxels based on our grid resolution + this.voxels = []; + for (var i = 0; i < this.res3; i++) { + var i3 = this.i1toi3(i); + + var _i3toPos = this.i3toPos(i3), + x = _i3toPos.x, + y = _i3toPos.y, + z = _i3toPos.z; + + var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth); + this.voxels.push(voxel); + + if (VISUAL_DEBUG) { + this.scene.add(voxel.wireframe); + this.scene.add(voxel.mesh); + } + } + } + }, { + key: 'setupMetaballs', + value: function setupMetaballs() { + + var x, y, z, vx, vy, vz, radius, pos, vel; + var matLambertWhite = LAMBERT_WHITE; + var maxRadiusTRippled = this.maxRadius * 3; + var maxRadiusDoubled = this.maxRadius * 2; + + // Randomly generate metaballs with different sizes and velocities + for (var i = 0; i < this.numMetaballs; i++) { + x = this.gridWidth / 2; + y = this.gridHeight / 2; + z = this.gridDepth / 2; + pos = new THREE.Vector3(3, 3, 3); + + vx = 0; + vy = (Math.random() * 2 - 1) * this.maxSpeedY; + vz = 0; + vel = new THREE.Vector3(vx, vy, vz); + + radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius; + var neg = 1; + if (Math.random() > 0.75) neg = -1; + var ball = new _metaball2.default(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG); + balls.push(ball); + + // if (VISUAL_DEBUG) { + // this.scene.add(ball.mesh); + // } + } + this.balls = balls; + } + }, { + key: 'update', + value: function update() { + + if (this.isPaused) { + return; + } + + // This should move the metaballs + balls.forEach(function (ball) { + ball.update(); + }); + this.balls = balls; + + for (var c = 0; c < this.res3; c++) { + // every voxel + + // Sampling the center and vertex points + this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos); + for (var i = 0; i < 8; i++) { + this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos); + } + + // Visualizing grid + if (VISUAL_DEBUG && this.showGrid) { + + // Toggle voxels on or off + if (this.voxels[c].center.isovalue > this.isolevel) { + this.voxels[c].show(); + } else { + this.voxels[c].hide(); + } + this.voxels[c].center.updateLabel(this.camera); + } else { + this.voxels[c].center.clearLabel(); + } + } + + this.updateMesh(); + } + }, { + key: 'pause', + value: function pause() { + this.isPaused = true; + } + }, { + key: 'play', + value: function play() { + this.isPaused = false; + } + }, { + key: 'show', + value: function show() { + for (var i = 0; i < this.res3; i++) { + this.voxels[i].show(); + } + this.showGrid = true; + } + }, { + key: 'hide', + value: function hide() { + for (var i = 0; i < this.res3; i++) { + this.voxels[i].hide(); + } + this.showGrid = false; + } + }, { + key: 'makeMesh', + value: function makeMesh() { + // @TODO + var geo = new THREE.Geometry(); + this.mesh = new THREE.Mesh(geo, LAVA_MAT); + this.mesh.geometry.dynamic = true; + this.scene.add(this.mesh); + } + }, { + key: 'updateMesh', + value: function updateMesh() { + // @TODO + var vertices = []; + var faces = []; + var count = 0; + for (var i = 0; i < this.res3; i++) { + var vox_count = 0; + var vANDn = this.voxels[i].polygonize(this.isolevel); + for (var j = 0; j < vANDn.vertPositions.length / 3; j++) { + var normals = []; + for (var k = 0; k < 3; k++) { + vertices.push(vANDn.vertPositions[vox_count]); + normals.push(vANDn.vertNormals[vox_count]); + vox_count++; + count++; + } + faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals)); + } + } + this.mesh.geometry.vertices = vertices; + //this.mesh.geometry.normals = normals; + this.mesh.geometry.faces = faces; + this.mesh.geometry.verticesNeedUpdate = true; + this.mesh.geometry.normalsNeedUpdate = true; + this.mesh.geometry.elementsNeedUpdate = true; + this.mesh.geometry.computeFaceNormals(); + //console.log(this.mesh); + } + }]); + + return MarchingCubes; + }(); + + exports.default = MarchingCubes; + ; + + // ------------------------------------------- // + + var Voxel = function () { + function Voxel(position, gridCellWidth, gridCellHeight, gridCellDepth) { + _classCallCheck(this, Voxel); + + this.init(position, gridCellWidth, gridCellHeight, gridCellDepth); + } + + _createClass(Voxel, [{ + key: 'init', + value: function init(position, gridCellWidth, gridCellHeight, gridCellDepth) { + this.pos = position; + this.gridCellWidth = gridCellWidth; + this.gridCellHeight = gridCellHeight; + this.gridCellDepth = gridCellDepth; + this.corners = []; + + if (VISUAL_DEBUG) { + this.makeMesh(); + } + + this.makeInspectPoints(); + } + }, { + key: 'makeMesh', + value: function makeMesh() { + var halfGridCellWidth = this.gridCellWidth / 2.0; + var halfGridCellHeight = this.gridCellHeight / 2.0; + var halfGridCellDepth = this.gridCellDepth / 2.0; + + var positions = new Float32Array([ + // Front face + halfGridCellWidth, halfGridCellHeight, halfGridCellDepth, halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth, -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth, -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth, + + // Back face + -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth, -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth, halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth, halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth]); + + var indices = new Uint16Array([0, 1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 4, 4, 3, 3, 0, 1, 6, 6, 5, 5, 2, 2, 1]); + + // Buffer geometry + var geo = new THREE.BufferGeometry(); + geo.setIndex(new THREE.BufferAttribute(indices, 1)); + geo.addAttribute('position', new THREE.BufferAttribute(positions, 3)); + + // Wireframe line segments + this.wireframe = new THREE.LineSegments(geo, WIREFRAME_MAT); + this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z); + + // Green cube + geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth); + this.mesh = new THREE.Mesh(geo, LAMBERT_GREEN); + this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); + } + }, { + key: 'makeInspectPoints', + value: function makeInspectPoints() { + var w = this.gridCellWidth / 2.0; + var h = this.gridCellHeight / 2.0; + var d = this.gridCellDepth / 2.0; + var x = this.pos.x; + var y = this.pos.y; + var z = this.pos.z; + var red = 0xff0000; + + // Center dot + this.center = new _inspect_point2.default(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x - w, y - h, z - d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x + w, y - h, z - d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x + w, y - h, z + d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x - w, y - h, z + d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x - w, y + h, z - d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x + w, y + h, z - d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x + w, y + h, z + d), 0, VISUAL_DEBUG)); + this.corners.push(new _inspect_point2.default(new THREE.Vector3(x - w, y + h, z + d), 0, VISUAL_DEBUG)); + } + }, { + key: 'show', + value: function show() { + if (this.mesh) { + this.mesh.visible = true; + } + if (this.wireframe) { + this.wireframe.visible = true; + } + } + }, { + key: 'hide', + value: function hide() { + if (this.mesh) { + this.mesh.visible = false; + } + + if (this.wireframe) { + this.wireframe.visible = false; + } + + if (this.center) { + this.center.clearLabel(); + } + } + }, { + key: 'vertexLerp', + value: function vertexLerp(isolevel, posA, posB) { + var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue); + var lerpPos = new THREE.Vector3(); + return lerpPos.lerpVectors(posA.pos, posB.pos, t); + } + + // returns an array of points on the cube edges + // null if no point exists for an edge + + }, { + key: 'edgePoints', + value: function edgePoints(edges, x) { + var points = [null, null, null, null, null, null, null, null, null, null, null, null]; + if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]); + if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]); + if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]); + if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]); + if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]); + if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]); + if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]); + if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]); + if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]); + if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]); + if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]); + if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]); + return points; + } + }, { + key: 'getNormal', + value: function getNormal(point) { + var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z); + var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z); + var x = sample(x1) - sample(x0); + var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z); + var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z); + var y = sample(y1) - sample(y0); + var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon); + var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon); + var z = sample(z1) - sample(z0); + var n = new THREE.Vector3(x, y, z); + return n.normalize(); + } + }, { + key: 'polygonize', + value: function polygonize(isolevel) { + + var vertexList = []; + var normalList = []; + var faceList = []; + + // get corner vertices that are inside metaballs + var corner = 1; + var allVert = 0; + for (var i = 0; i < 8; i++) { + if (this.corners[i].isovalue > isolevel) { + allVert |= corner; + } + corner = corner << 1; + } + + if (allVert != 0) { + // get intersected edges + var edges = _marching_cube_LUT2.default.EDGE_TABLE[allVert]; + + // get 12 points + var points = this.edgePoints(edges, isolevel); + + for (var j = 0; j < 16; j++) { + var tri = _marching_cube_LUT2.default.TRI_TABLE[allVert * 16 + j]; + if (tri < 0) break; + var vertex = points[tri]; + vertexList.push(vertex); + normalList.push(this.getNormal(vertex)); + } + } + + return { + vertPositions: vertexList, + vertNormals: normalList + }; + } + }]); + + return Voxel; + }(); + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var THREE = __webpack_require__(2); + + var SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32); + var LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x9EB3D8, transparent: true, opacity: 0.5 }); + + var Metaball = function () { + function Metaball(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) { + _classCallCheck(this, Metaball); + + this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug); + } + + _createClass(Metaball, [{ + key: 'init', + value: function init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) { + this.gridWidth = gridWidth; + this.gridHeight = gridHeight; + this.gridDepth = gridDepth; + this.pos = pos; + this.vel = vel; + this.neg = neg; + this.radius = radius; + this.radius2 = radius * radius; + this.mesh = null; + this.debug = visualDebug; + // if (visualDebug) { + // this.makeMesh(); + // } + } + }, { + key: 'makeMesh', + value: function makeMesh() { + this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE); + this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); + this.mesh.scale.set(this.radius, this.radius, this.radius); + } + }, { + key: 'show', + value: function show() { + if (this.mesh) { + this.mesh.visible = true; + } + } + }, { + key: 'hide', + value: function hide() { + if (this.mesh) { + this.mesh.visible = false; + } + } + }, { + key: 'update', + value: function update() { + + // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z); + // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir); + // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2)); + // if ((dist + 2*this.radius) > this.gridWidth + // || (dist + 2*this.radius) > this.gridDepth) { + // this.vel.add(disp); + // } + var y = this.pos.y + this.radius > this.gridHeight || this.pos.y + 2 * this.radius < 0; + if (y) this.vel.y *= -1; + + var date = new Date(); + var velocity = new THREE.Vector3(); + velocity.copy(this.vel).multiplyScalar(3); + this.pos.add(velocity); + + // if (x || y || z) { + // this.vel.multiplyScalar(-1); + // } + if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z); + } + }]); + + return Metaball; + }(); + + exports.default = Metaball; + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var THREE = __webpack_require__(2); + + var POINT_MATERIAL = new THREE.PointsMaterial({ color: 0xee1111, size: 10, sizeAttenuation: true }); + + var InspectPoint = function () { + function InspectPoint(pos, isovalue, visualDebug) { + _classCallCheck(this, InspectPoint); + + this.init(pos, isovalue, visualDebug); + } + + _createClass(InspectPoint, [{ + key: 'init', + value: function init(pos, isovalue, visualDebug) { + this.pos = pos; + this.isovalue = isovalue; + this.label = null; + + if (visualDebug) { + this.makeLabel(); + } + } + }, { + key: 'makeLabel', + + + // Create an HTML div for holding label + value: function makeLabel() { + this.label = document.createElement('div'); + this.label.style.position = 'absolute'; + this.label.style.width = 100; + this.label.style.height = 100; + this.label.style.userSelect = 'none'; + this.label.style.cursor = 'default'; + this.label.style.fontSize = '0.3em'; + this.label.style.pointerEvents = 'none'; + document.body.appendChild(this.label); + } + }, { + key: 'updateLabel', + value: function updateLabel(camera) { + if (this.label) { + var screenPos = this.pos.clone().project(camera); + screenPos.x = (screenPos.x + 1) / 2 * window.innerWidth;; + screenPos.y = -(screenPos.y - 1) / 2 * window.innerHeight;; + + this.label.style.top = screenPos.y + 'px'; + this.label.style.left = screenPos.x + 'px'; + this.label.innerHTML = this.isovalue.toFixed(2); + this.label.style.opacity = this.isovalue - 0.5; + } + } + }, { + key: 'clearLabel', + value: function clearLabel() { + if (this.label) { + this.label.innerHTML = ''; + this.label.style.opacity = 0; + } + } + }]); + + return InspectPoint; + }(); + + exports.default = InspectPoint; + +/***/ }, +/* 14 */ +/***/ function(module, exports) { + + module.exports = "\r\nvarying vec3 f_normal;\r\nvarying vec3 e_position;\r\n\r\n// uv, position, projectionMatrix, modelViewMatrix, normal\r\nvoid main() {\r\n f_normal = normalMatrix * normal;\r\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}" + +/***/ }, +/* 15 */ +/***/ function(module, exports) { + + module.exports = "\r\nuniform sampler2D texture;\r\nuniform vec3 u_ambient;\r\nuniform vec3 u_lightCol;\r\nuniform float u_lightIntensity;\r\n\r\nvarying vec3 f_normal;\r\nvarying vec3 e_position;\r\n\r\nvoid main() {\r\n\tvec3 ref = reflect(e_position, f_normal);\r\n\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\r\n float x = f_normal.x/m + 0.5;\r\n float y = f_normal.y/m + 0.5;\r\n\r\n vec4 color = texture2D(texture, vec2(x,y));\r\n\r\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\r\n}" + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__.p + "index.html"; + +/***/ }, +/* 17 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = function (THREE) { + + /** + * @author mrdoob / http://mrdoob.com/ + */ + THREE.OBJLoader = function (manager) { + + this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager; + }; + + THREE.OBJLoader.prototype = { + + constructor: THREE.OBJLoader, + + load: function load(url, onLoad, onProgress, onError) { + + var scope = this; + + var loader = new THREE.XHRLoader(scope.manager); + loader.load(url, function (text) { + + onLoad(scope.parse(text)); + }, onProgress, onError); + }, + + parse: function parse(text) { + + console.time('OBJLoader'); + + var object, + objects = []; + var geometry, material; + + function parseVertexIndex(value) { + + var index = parseInt(value); + + return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3; + } + + function parseNormalIndex(value) { + + var index = parseInt(value); + + return (index >= 0 ? index - 1 : index + normals.length / 3) * 3; + } + + function parseUVIndex(value) { + + var index = parseInt(value); + + return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2; + } + + function addVertex(a, b, c) { + + geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]); + } + + function addNormal(a, b, c) { + + geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]); + } + + function addUV(a, b, c) { + + geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]); + } + + function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) { + + var ia = parseVertexIndex(a); + var ib = parseVertexIndex(b); + var ic = parseVertexIndex(c); + var id; + + if (d === undefined) { + + addVertex(ia, ib, ic); + } else { + + id = parseVertexIndex(d); + + addVertex(ia, ib, id); + addVertex(ib, ic, id); + } + + if (ua !== undefined) { + + ia = parseUVIndex(ua); + ib = parseUVIndex(ub); + ic = parseUVIndex(uc); + + if (d === undefined) { + + addUV(ia, ib, ic); + } else { + + id = parseUVIndex(ud); + + addUV(ia, ib, id); + addUV(ib, ic, id); + } + } + + if (na !== undefined) { + + ia = parseNormalIndex(na); + ib = parseNormalIndex(nb); + ic = parseNormalIndex(nc); + + if (d === undefined) { + + addNormal(ia, ib, ic); + } else { + + id = parseNormalIndex(nd); + + addNormal(ia, ib, id); + addNormal(ib, ic, id); + } + } + } + + // create mesh if no objects in text + + if (/^o /gm.test(text) === false) { + + geometry = { + vertices: [], + normals: [], + uvs: [] + }; + + material = { + name: '' + }; + + object = { + name: '', + geometry: geometry, + material: material + }; + + objects.push(object); + } + + var vertices = []; + var normals = []; + var uvs = []; + + // v float float float + + var vertex_pattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; + + // vn float float float + + var normal_pattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; + + // vt float float + + var uv_pattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; + + // f vertex vertex vertex ... + + var face_pattern1 = /f( +-?\d+)( +-?\d+)( +-?\d+)( +-?\d+)?/; + + // f vertex/uv vertex/uv vertex/uv ... + + var face_pattern2 = /f( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))?/; + + // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... + + var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; + + // f vertex//normal vertex//normal vertex//normal ... + + var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/; + + // + + var lines = text.split('\n'); + + for (var i = 0; i < lines.length; i++) { + + var line = lines[i]; + line = line.trim(); + + var result; + + if (line.length === 0 || line.charAt(0) === '#') { + + continue; + } else if ((result = vertex_pattern.exec(line)) !== null) { + + // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"] + + vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])); + } else if ((result = normal_pattern.exec(line)) !== null) { + + // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"] + + normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])); + } else if ((result = uv_pattern.exec(line)) !== null) { + + // ["vt 0.1 0.2", "0.1", "0.2"] + + uvs.push(parseFloat(result[1]), parseFloat(result[2])); + } else if ((result = face_pattern1.exec(line)) !== null) { + + // ["f 1 2 3", "1", "2", "3", undefined] + + addFace(result[1], result[2], result[3], result[4]); + } else if ((result = face_pattern2.exec(line)) !== null) { + + // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] + + addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]); + } else if ((result = face_pattern3.exec(line)) !== null) { + + // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined] + + addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]); + } else if ((result = face_pattern4.exec(line)) !== null) { + + // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] + + addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]); + } else if (/^o /.test(line)) { + + geometry = { + vertices: [], + normals: [], + uvs: [] + }; + + material = { + name: '' + }; + + object = { + name: line.substring(2).trim(), + geometry: geometry, + material: material + }; + + objects.push(object); + } else if (/^g /.test(line)) { + + // group + + } else if (/^usemtl /.test(line)) { + + // material + + material.name = line.substring(7).trim(); + } else if (/^mtllib /.test(line)) { + + // mtl file + + } else if (/^s /.test(line)) { + + // smooth shading + + } else { + + // console.log( "THREE.OBJLoader: Unhandled line " + line ); + + } + } + + var container = new THREE.Object3D(); + var l; + + for (i = 0, l = objects.length; i < l; i++) { + + object = objects[i]; + geometry = object.geometry; + + var buffergeometry = new THREE.BufferGeometry(); + + buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3)); + + if (geometry.normals.length > 0) { + + buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3)); + } + + if (geometry.uvs.length > 0) { + + buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2)); + } + + material = new THREE.MeshLambertMaterial({ + color: 0xff0000 + }); + material.name = object.material.name; + + var mesh = new THREE.Mesh(buffergeometry, material); + mesh.name = object.name; + + container.add(mesh); + } + + console.timeEnd('OBJLoader'); + + return container; + } + + }; + }; + +/***/ }, +/* 18 */ +/***/ function(module, exports) { + + module.exports = "varying vec3 f_normal;\r\nvarying vec3 f_position;\r\nvarying vec3 e_position;\r\n\r\n// uv, position, projectionMatrix, modelViewMatrix, normal\r\nvoid main() {\r\n f_normal = normal;\r\n f_position = position;\r\n e_position = cameraPosition;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n" + +/***/ }, +/* 19 */ +/***/ function(module, exports) { + + module.exports = "#define M_PI 3.1415926535897932384626433832795\r\n\r\nuniform vec3 u_lightCol;\r\nuniform float u_lightIntensity;\r\n\r\nvarying vec3 f_position;\r\nvarying vec3 f_normal;\r\nvarying vec3 e_position;\r\n\r\nfloat cosine(float a, float b, float c, float d, float t) {\r\n\treturn a + b * cos(2.0 * M_PI * (c * t + d));\r\n}\r\n\r\nvoid main() {\r\n\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\r\n\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\r\n\r\n gl_FragColor = vec4(d,d,d, 1.0);\r\n}\r\n" + +/***/ }, +/* 20 */ +/***/ function(module, exports) { + + module.exports = "varying vec3 f_normal;\r\nvarying vec3 f_position;\r\n\r\n// uv, position, projectionMatrix, modelViewMatrix, normal\r\nvoid main() {\r\n f_normal = normal;\r\n f_position = position;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n" + +/***/ }, +/* 21 */ +/***/ function(module, exports) { + + module.exports = "uniform vec3 u_lightPos;\r\nuniform vec3 u_lightCol;\r\nuniform float u_lightIntensity;\r\n\r\nvarying vec3 f_position;\r\nvarying vec3 f_normal;\r\n\r\nvoid main() {\r\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\r\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\r\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\r\n}\r\n" + +/***/ } +/******/ ]); +//# sourceMappingURL=bundle.js.map \ No newline at end of file diff --git a/build/bundle.js.map b/build/bundle.js.map new file mode 100644 index 0000000..0f8563b --- /dev/null +++ b/build/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap 814670acf2567ec58054","webpack:///./src/main.js","webpack:///./src/textures.js","webpack:///./~/three/build/three.js","webpack:///./src/assets/silver.bmp","webpack:///./src/framework.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/three-orbit-controls/index.js","webpack:///./src/marching_cube_LUT.js","webpack:///./src/marching_cubes.js","webpack:///./src/metaball.js","webpack:///./src/inspect_point.js","webpack:///./src/shaders/lava-vert.glsl","webpack:///./src/shaders/lava-frag.glsl","webpack:///./index.html","webpack:///./~/three-obj-loader/dist/index.js","webpack:///./src/shaders/glass-vert.glsl","webpack:///./src/shaders/glass-frag.glsl","webpack:///./src/shaders/metal-vert.glsl","webpack:///./src/shaders/metal-frag.glsl"],"names":["require","THREE","OBJLoader","DEFAULT_VISUAL_DEBUG","DEFAULT_ISO_LEVEL","DEFAULT_GRID_RES","DEFAULT_GRID_WIDTH","DEFAULT_GRID_HEIGHT","DEFAULT_GRID_DEPTH","DEFAULT_NUM_METABALLS","DEFAULT_MIN_RADIUS","DEFAULT_MAX_RADIUS","DEFAULT_MAX_SPEEDX","DEFAULT_MAX_SPEEDY","options","lightColor","lightIntensity","ambient","albedo","loaded","red","Color","green","glassGeo","lampGeo","g_mat","uniforms","u_albedo","type","value","u_ambient","u_lightCol","u_lightIntensity","vertexShader","fragmentShader","m_mat","GLASS_MAT","MeshLambertMaterial","color","emissive","transparent","opacity","METAL_MAT","MeshPhongMaterial","App","marchingCubes","undefined","config","visualDebug","isolevel","gridRes","gridWidth","gridHeight","gridDepth","gridCellWidth","gridCellHeight","gridCellDepth","numMetaballs","minRadius","maxRadius","maxSpeedX","maxSpeedY","maxSpeedZ","camera","scene","renderer","isPaused","onLoad","framework","gui","stats","setClearColor","objLoader","obj","load","children","geometry","glass","Mesh","translateX","translateZ","add","lamp","setupCamera","setupLights","setupScene","setupGUI","cosine","a","b","c","d","t","Math","cos","PI","onUpdate","date","Date","sec","getSeconds","r","g","set","update","position","lookAt","Vector3","directionalLight","DirectionalLight","setHSL","multiplyScalar","init","silverTexture","Promise","resolve","reject","TextureLoader","texture","OrbitControls","callback","setMode","domElement","style","left","top","document","body","appendChild","GUI","autoPlace","window","addEventListener","Scene","PerspectiveCamera","innerWidth","innerHeight","WebGLRenderer","antialias","alpha","setPixelRatio","devicePixelRatio","setSize","controls","enableDamping","enableZoom","target","rotateSpeed","zoomSpeed","panSpeed","hasMoved","aspect","updateProjectionMatrix","tick","begin","render","end","requestAnimationFrame","EDGE_TABLE","Int32Array","TRI_TABLE","VISUAL_DEBUG","episolon","balls","l_mat","LAVA_MAT","ShaderMaterial","LAMBERT_WHITE","LAMBERT_GREEN","MeshBasicMaterial","WIREFRAME_MAT","LineBasicMaterial","linewidth","sample","point","isovalue","i","length","radius","distanceTo","pos","MarchingCubes","origin","halfCellWidth","halfCellHeight","halfCellDepth","res","res2","res3","voxels","showSpheres","showGrid","then","material","setupCells","setupMetaballs","makeMesh","i1","i3x","i3y","i3z","i3","x","y","z","i1toi3","i3toPos","voxel","Voxel","push","wireframe","mesh","vx","vy","vz","vel","matLambertWhite","maxRadiusTRippled","maxRadiusDoubled","random","neg","ball","forEach","center","corners","show","hide","updateLabel","clearLabel","updateMesh","geo","Geometry","dynamic","vertices","faces","count","vox_count","vANDn","polygonize","j","vertPositions","normals","k","vertNormals","Face3","verticesNeedUpdate","normalsNeedUpdate","elementsNeedUpdate","computeFaceNormals","makeInspectPoints","halfGridCellWidth","halfGridCellHeight","halfGridCellDepth","positions","Float32Array","indices","Uint16Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","BoxBufferGeometry","w","h","visible","posA","posB","lerpPos","lerpVectors","edges","points","vertexLerp","x0","x1","y0","y1","z0","z1","n","normalize","vertexList","normalList","faceList","corner","allVert","edgePoints","tri","vertex","getNormal","SPHERE_GEO","SphereBufferGeometry","Metaball","radius2","debug","scale","velocity","copy","POINT_MATERIAL","PointsMaterial","size","sizeAttenuation","InspectPoint","label","makeLabel","createElement","width","height","userSelect","cursor","fontSize","pointerEvents","screenPos","clone","project","innerHTML","toFixed"],"mappings":"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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,0BAA0B;;AAEhE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC;;AAEvC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,6BAA4B,gBAAgB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,kBAAiB;;AAEjB;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;;AAEA;;AAEA;AACA;AACA,uDAAsD;;AAEtD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA,oEAAmE;;AAEnE;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IA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A;;AAEA,IAAG;;;;AAIH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AA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A;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;AACA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,2BAA0B,sBAAsB;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,sBAAqB,mBAAmB;;AAExC;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;;AAEA;;AAEA;;AAEA,MAAK;;AAEL,sBAAqB,oBAAoB;;AAEzC;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ,qBAAoB,0BAA0B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;AACA,wBAAuB;;AAEvB;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA,oCAAmC,QAAQ;;AAE3C;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mDAAkD,QAAQ;;AAE1D;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAiC,QAAQ;;AAEzC;;AAEA;;AAEA;;AAEA;;AAEA,qCAAoC,QAAQ;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;;AAEA,yBAAwB;AACxB;;AAEA;AACA,4BAA2B;AAC3B;AACA;AACA;;AAEA,2CAA0C,QAAQ;;AAElD;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,qBAAoB,OAAO;;AAE3B;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,YAAY;;AAE/B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,oBAAmB,YAAY;;AAE/B;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,0BAA0B;;AAE7C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,uBAAuB;;AAE1C;;AAEA;AACA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA;;AAEA,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,kDAAiD;AACjD;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,uCAAsC,QAAQ;;AAE9C;;AAEA;;AAEA,sDAAqD,QAAQ;;AAE7D;;AAEA;;AAEA;;AAEA;;AAEA,gDAA+C,QAAQ;;AAEvD;;AAEA,uCAAsC,QAAQ;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA,GAAE;;AAEF;AACA,8BAA6B,kBAAkB;;AAE/C;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,oBAAmB,kBAAkB;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,kBAAkB;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,6CAA4C,QAAQ;;AAEpD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,iDAAgD,4BAA4B;;AAE5E;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA,sBAAqB,cAAc;;AAEnC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB,eAAe;;AAE/B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,+EAA8E,kCAAkC;;AAEhH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,OAAO;;AAEjD;AACA;AACA;;AAEA;;AAEA;;AAEA,sDAAqD;AACrD;;AAEA;;AAEA;;AAEA,OAAM;;;AAGN,6CAA4C,OAAO;;AAEnD;AACA;AACA;;AAEA;;AAEA;;AAEA,gCAA+B;AAC/B;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,yCAAwC,QAAQ;;AAEhD;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,kDAAiD,QAAQ;;AAEzD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,oGAAmG;AACnG,oGAAmG;AACnG,oGAAmG;AACnG,oGAAmG;AACnG,oGAAmG;AACnG,oGAAmG;;AAEnG;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,sCAAqC;AACrC,sCAAqC;AACrC,sCAAqC;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;AACA,uBAAsB;AACtB,uBAAsB;AACtB,uBAAsB;;AAEtB,qBAAoB;;AAEpB;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,qBAAoB,aAAa;;AAEjC;;AAEA,sBAAqB,aAAa;;AAElC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B,kBAAiB,YAAY;;AAE7B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,oBAAmB,aAAa;;AAEhC;;AAEA,qBAAoB,aAAa;;AAEjC;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,YAAY;;AAE/B,qBAAoB,YAAY;;AAEhC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kEAAiE;;AAEjE;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB,kBAAkB;;AAEpC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oDAAmD,+DAA+D,EAAE;;AAEpH;;AAEA;;AAEA;AACA,oDAAmD,0DAA0D,EAAE;;AAE/G;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,oDAAmD,oDAAoD,EAAE;;AAEzG;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,YAAY,aAAa,eAAe,GAAG;;AAEnF;;AAEA;;AAEA,oCAAmC,qBAAqB;;AAExD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,mDAAkD;AAClD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,+BAA8B;AAC9B,mCAAkC;AAClC,oCAAmC;AACnC,8BAA6B;AAC7B,gCAA+B;AAC/B,kCAAiC;;AAEjC,8BAA6B;AAC7B,4BAA2B;AAC3B,wBAAuB;;AAEvB;;AAEA,4BAA2B;;AAE3B;;AAEA;;AAEA,mCAAkC;AAClC,mCAAkC;AAClC,mCAAkC;AAClC,mCAAkC;;AAElC;;AAEA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA;;AAEA;;AAEA,gCAA+B;AAC/B,iCAAgC;;AAEhC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mDAAkD;AAClD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,8BAA6B;AAC7B,kCAAiC;;AAEjC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,KAAI;;AAEJ;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;;AAGH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;AACA;;AAEA,gCAA+B;;AAE/B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;AACA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,mDAAkD,OAAO;;AAEzD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,OAAO;;AAE3B;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;;;AAIA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sBAAqB,OAAO;;AAE5B;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,sBAAqB,OAAO;;AAE5B;;AAEA;;AAEA;;AAEA,SAAQ;;AAER;;AAEA;;AAEA,QAAO;;AAEP;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA,WAAU;;AAEV;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,KAAI;;AAEJ,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,sBAAqB,OAAO;;AAE5B;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,OAAO;;AAE3B;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB,OAAO;;AAE3B;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,m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AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AA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CA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AA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EA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA,qCAAoC;AACpC;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,wBAAuB,iBAAiB;;AAExC;;AAEA;;AAEA;;AAEA,6CAA4C,oBAAoB;;AAEhE;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,sCAAqC,QAAQ;;AAE7C;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB,WAAW;;AAEjC,uBAAsB;;AAEtB,wBAAuB,0BAA0B;;AAEjD;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;;AAGJ;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,oBAAmB,iBAAiB;;AAEpC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;;;AAIA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,oDAAmD;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA,oDAAmD;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;;AAEA,8BAA6B;;AAE7B;;AAEA,+CAA8C;;AAE9C,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA,oBAAmB,SAAS;;AAE5B;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;AACA;;AAEA,mCAAkC,uBAAuB;;AAEzD;;AAEA,qBAAoB,cAAc;;AAElC;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oCAAmC;;AAEnC;AACA,sCAAqC;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;AACA,0CAAyC;;AAEzC;;AAEA;;AAEA,MAAK;;AAEL,KAAI;AACJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL,KAAI;AACJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,oCAAmC,EAAE;;AAErC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,sCAAqC;;AAErC;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe;AACf;;AAEA;;AAEA;;AAEA,oCAAmC,EAAE;;AAErC;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;;AAErC;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA,uBAAsB;;AAEtB;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,oBAAmB,cAAc;;AAEjC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,oBAAmB,cAAc;;AAEjC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,oBAAmB,cAAc;;AAEjC;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,OAAM;;AAEN,kCAAiC;;AAEjC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,sCAAqC,SAAS;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,sCAAqC,SAAS;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB,aAAa;;AAE/B;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,SAAS;;AAEjD;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,mBAAkB,eAAe;;AAEjC;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,uBAAsB,cAAc;;AAEpC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,uBAAsB,cAAc;;AAEpC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yFAAwF,cAAc;;AAEtG;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,oCAAmC,gBAAgB;;AAEnD;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;AACA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oCAAmC;;AAEnC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,SAAS;;AAE/C;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,oBAAmB,wBAAwB;;AAE3C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,oBAAmB,wBAAwB;;AAE3C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,2CAA0C,SAAS;;AAEnD;;AAEA;;AAEA;;AAEA,IAAG;;;AAGH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,2CAA0C,SAAS;;AAEnD;;AAEA;;AAEA;;AAEA,IAAG;;;AAGH;;AAEA;AACA;;AAEA,oBAAmB,qBAAqB;;AAExC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,8CAA6C,QAAQ;;AAErD;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,oBAAmB,4BAA4B;;AAE/C;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB,0BAA0B;;AAE/C;;AAEA,wBAAuB,0CAA0C;;AAEjE;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,oDAAmD;;AAEnD;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;AACL;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,gDAA+C,OAAO;;AAEtD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;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;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0FAAyF,4CAA4C;AACrI;;AAEA;AACA;AACA,8FAA6F,4CAA4C;AACzI;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;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CA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AA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;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB,gCAA+B;;AAE/B;AACA;AACA,qCAAoC;AACpC,mCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;;AAEzB;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;;AAEA;AACA,gBAAe;;AAEf;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA,sBAAqB;AACrB,qBAAoB;AACpB,mBAAkB;;AAElB,gBAAe;;AAEf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AA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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 814670acf2567ec58054","require('file-loader?name=[name].[ext]!../index.html');\r\nimport {silverTexture} from './textures'\r\n//import {quote} from './quote'\r\n// Credit:\r\n// http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/\r\n// http://paulbourke.net/geometry/polygonise/\r\n\r\nconst THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much\r\nconst OBJLoader = require('three-obj-loader');\r\nOBJLoader(THREE)\r\n\r\nimport Framework from './framework'\r\nimport LUT from './marching_cube_LUT.js'\r\nimport MarchingCubes from './marching_cubes.js'\r\n\r\nconst DEFAULT_VISUAL_DEBUG = false;\r\nconst DEFAULT_ISO_LEVEL = 1.0;\r\nconst DEFAULT_GRID_RES = 30;\r\nconst DEFAULT_GRID_WIDTH = 6;\r\nconst DEFAULT_GRID_HEIGHT = 17;\r\nconst DEFAULT_GRID_DEPTH = 6;\r\nconst DEFAULT_NUM_METABALLS = 10;\r\nconst DEFAULT_MIN_RADIUS = 0.5;\r\nconst DEFAULT_MAX_RADIUS = 1;\r\nconst DEFAULT_MAX_SPEEDX = 0.005;\r\nconst DEFAULT_MAX_SPEEDY = 0.03;\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'};\r\nvar loaded = false;\r\nvar red = new THREE.Color(1.0,0.0,0.0);\r\nvar green = new THREE.Color(0.0,1.0,0.0);\r\nvar glassGeo;\r\nvar lampGeo;\r\n\r\n// glass, emissive, iridescent\r\nvar g_mat = {\r\n uniforms: {\r\n u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/glass-vert.glsl'),\r\n fragmentShader: require('./shaders/glass-frag.glsl')\r\n};\r\n\r\n// metal\r\nvar m_mat = {\r\n uniforms: {\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/metal-vert.glsl'),\r\n fragmentShader: require('./shaders/metal-frag.glsl')\r\n};\r\n\r\n//const GLASS_MAT = new THREE.ShaderMaterial(g_mat);\r\nvar GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3});\r\nvar METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111});\r\n\r\nvar App = {\r\n //\r\n marchingCubes: undefined,\r\n config: {\r\n // Global control of all visual debugging.\r\n // This can be set to false to disallow any memory allocation of visual debugging components.\r\n // **Note**: If your application experiences performance drop, disable this flag.\r\n visualDebug: DEFAULT_VISUAL_DEBUG,\r\n\r\n // The isolevel for marching cubes\r\n isolevel: DEFAULT_ISO_LEVEL,\r\n\r\n // Grid resolution in each dimension. If gridRes = 4, then we have a 4x4x4 grid\r\n gridRes: DEFAULT_GRID_RES,\r\n\r\n // Total width of grid\r\n gridWidth: DEFAULT_GRID_WIDTH,\r\n\r\n gridHeight: DEFAULT_GRID_HEIGHT,\r\n\r\n gridDepth: DEFAULT_GRID_DEPTH,\r\n\r\n // Width of each voxel\r\n // Ideally, we want the voxel to be small (higher resolution)\r\n gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES,\r\n gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES,\r\n gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES,\r\n\r\n // Number of metaballs\r\n numMetaballs: DEFAULT_NUM_METABALLS,\r\n\r\n // Minimum radius of a metaball\r\n minRadius: DEFAULT_MIN_RADIUS,\r\n\r\n // Maxium radius of a metaball\r\n maxRadius: DEFAULT_MAX_RADIUS,\r\n\r\n // Maximum speed of a metaball\r\n maxSpeedX: DEFAULT_MAX_SPEEDX,\r\n maxSpeedY: DEFAULT_MAX_SPEEDY,\r\n maxSpeedZ: DEFAULT_MAX_SPEEDX, \r\n },\r\n\r\n // Scene's framework objects\r\n camera: undefined,\r\n scene: undefined,\r\n renderer: undefined,\r\n\r\n // Play/pause control for the simulation\r\n isPaused: false,\r\n color: 0xffffff\r\n};\r\n\r\n// called after the scene loads\r\nfunction onLoad(framework) {\r\n\r\n var {scene, camera, renderer, gui, stats} = framework;\r\n App.scene = scene;\r\n App.camera = camera;\r\n App.renderer = renderer;\r\n\r\n renderer.setClearColor( 0x111111 );\r\n //scene.add(new THREE.AxisHelper(20));\r\n\r\n var objLoader = new THREE.OBJLoader();\r\n var obj = objLoader.load('glass.obj', function(obj) {\r\n glassGeo = obj.children[0].geometry;\r\n var glass = new THREE.Mesh(glassGeo, GLASS_MAT);\r\n glass.translateX(-1.5);\r\n glass.translateZ(-1.5);\r\n App.scene.add(glass);\r\n loaded = true;\r\n });\r\n\r\n var obj = objLoader.load('lamp.obj', function(obj) {\r\n lampGeo = obj.children[0].geometry;\r\n var lamp = new THREE.Mesh(lampGeo, METAL_MAT);\r\n lamp.translateX(-1.5);\r\n lamp.translateZ(-1.5);\r\n App.scene.add(lamp);\r\n });\r\n\r\n setupCamera(App.camera);\r\n setupLights(App.scene);\r\n setupScene(App.scene);\r\n setupGUI(gui);\r\n}\r\n\r\nfunction cosine(a,b,c,d,t) {\r\n return a + b * Math.cos(2.0 * Math.PI * (c * t + d));\r\n}\r\n\r\n// called on frame updates\r\nfunction onUpdate(framework) {\r\n if (loaded) {\r\n var date = new Date();\r\n var sec = date.getSeconds();\r\n var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0);\r\n var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0);\r\n var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); \r\n GLASS_MAT.emissive.set(new THREE.Color(r,g,b));\r\n }\r\n if (App.marchingCubes) {\r\n App.marchingCubes.update();\r\n }\r\n}\r\n\r\nfunction setupCamera(camera) {\r\n // set camera position\r\n camera.position.set(25, 10, 25);\r\n camera.lookAt(new THREE.Vector3(8,0,-5));\r\n}\r\n\r\nfunction setupLights(scene) {\r\n\r\n // Directional light\r\n var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );\r\n directionalLight.color.setHSL(0.1, 1, 0.95);\r\n directionalLight.position.set(1, 10, 2);\r\n directionalLight.position.multiplyScalar(10);\r\n\r\n scene.add(directionalLight);\r\n}\r\n\r\nfunction setupScene(scene) {\r\n App.marchingCubes = new MarchingCubes(App);\r\n}\r\n\r\nfunction setupGUI(gui) {\r\n\r\n // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage\r\n\r\n\r\n // gui.add(App, 'isPaused').onChange(function(value) {\r\n // App.isPaused = value;\r\n // if (value) {\r\n // App.marchingCubes.pause();\r\n // } else {\r\n // App.marchingCubes.play();\r\n // }\r\n // });\r\n\r\n // gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) {\r\n // App.config.numMetaballs = value;\r\n // App.marchingCubes.init(App);\r\n // });\r\n\r\n // --- DEBUG ---\r\n\r\n // var debugFolder = gui.addFolder('Debug');\r\n // debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) {\r\n // App.marchingCubes.showGrid = value;\r\n // if (value) {\r\n // App.marchingCubes.show();\r\n // } else {\r\n // App.marchingCubes.hide();\r\n // }\r\n // });\r\n\r\n // debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) {\r\n // App.marchingCubes.showSpheres = value;\r\n // if (value) {\r\n // for (var i = 0; i < App.config.numMetaballs; i++) {\r\n // App.marchingCubes.balls[i].show();\r\n // }\r\n // } else {\r\n // for (var i = 0; i < App.config.numMetaballs; i++) {\r\n // App.marchingCubes.balls[i].hide();\r\n // }\r\n // }\r\n // });\r\n // debugFolder.open();\r\n}\r\n\r\n// when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate\r\nFramework.init(onLoad, onUpdate);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n// this file is just for convenience. it sets up loading the mario obj and texture\r\n\r\nconst THREE = require('three');\r\n\r\nexport var silverTexture = new Promise((resolve, reject) => {\r\n (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) {\r\n resolve(texture);\r\n })\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/textures.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*(\\S*)\\s*\\(/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tObject.assign( EventDispatcher.prototype, {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\tvar REVISION = '82';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar BlendingMode = {\n\t\tNoBlending: NoBlending,\n\t\tNormalBlending: NormalBlending,\n\t\tAdditiveBlending: AdditiveBlending,\n\t\tSubtractiveBlending: SubtractiveBlending,\n\t\tMultiplyBlending: MultiplyBlending,\n\t\tCustomBlending: CustomBlending\n\t};\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar TextureMapping = {\n\t\tUVMapping: UVMapping,\n\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t};\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar TextureWrapping = {\n\t\tRepeatWrapping: RepeatWrapping,\n\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t};\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar TextureFilter = {\n\t\tNearestFilter: NearestFilter,\n\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\tLinearFilter: LinearFilter,\n\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t};\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\trandom16: function () {\n\n\t\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\t\treturn Math.random();\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: TextureIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.sourceFile = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\tvar count = 0;\n\tfunction TextureIdCount() { return count++; }\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\t\t\tthis.w = attribute.array[ index + 3 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyProjection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 projection matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\t\t\tvar d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide\n\n\t\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;\n\t\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;\n\t\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix4( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeFrustum: function ( left, right, bottom, top, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakePerspective: function ( fov, aspect, near, far ) {\n\n\t\t\tvar ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 );\n\t\t\tvar ymin = - ymax;\n\t\t\tvar xmin = ymin * aspect;\n\t\t\tvar xmax = ymax * aspect;\n\n\t\t\treturn this.makeFrustum( xmin, xmax, ymin, ymax, near, far );\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\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}\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\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}\\n\";\n\n\tvar 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\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n float maxComponent = max( max( value.r, value.g ), value.b );\\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n M = ceil( M * 255.0 ) / 255.0;\\n return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float D = max( maxRange / maxRGB, 1.0 );\\n D = min( floor( D ) / 255.0, 1.0 );\\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n vec4 vResult;\\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n vResult.w = fract(Le);\\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n return 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 float Le = value.z * 255.0 + value.w;\\n vec3 Xp_Y_XYZp;\\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\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\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color = pointLight.color;\\n\\t\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\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_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\\t#include \\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\\t#include \\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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar 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};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\\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_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar 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\";\n\n\tvar 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}\\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_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\";\n\n\tvar 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 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\\t\\t\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n return 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 return ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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 boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n return 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 color *= toneMappingExposure;\\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n color = max( vec3( 0.0 ), color - 0.004 );\\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar 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\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\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\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\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\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse = vec3( 0.0 );\\n\\treflectedLight.directSpecular = vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse = diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular = vec3( 0.0 );\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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 \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\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 \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\n}\\n\";\n\n\tvar normal_vert = \"varying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvNormal = normalize( normalMatrix * normal );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( (value && value.isColor) ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular : { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity : { value: 1 }, // temporary\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\n\t\t\t\t{\n\t\t\t\t\tscale : { value: 1 },\n\t\t\t\t\tdashSize : { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: {\n\n\t\t\t\topacity : { value: 1.0 }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\n\t\t\t\tlightPos: { value: new Vector3() }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\tShaderLib.standard.uniforms,\n\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t point.y < this.min.y || point.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyProjection( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( (fog && fog.isFog) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( (fog && fog.isFogExp2) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: MaterialIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( (currentValue && currentValue.isColor) ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( (currentValue && currentValue.isVector3) && (newValue && newValue.isVector3) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( (this.color && this.color.isColor) ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();\n\t\t\tif ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\n\t\t\tif ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.bumpMap && this.bumpMap.isTexture) ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( (this.normalMap && this.normalMap.isTexture) ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( (this.displacementMap && this.displacementMap.isTexture) ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.envMap && this.envMap.isTexture) ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\tvar count$1 = 0;\n\tfunction MaterialIdCount() { return count$1++; }\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tthis.makeEmpty();\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tvar array, offset, stride;\n\n\t\t\t\t\t\t\t\tif ( (attribute && attribute.isInterleavedBufferAttribute) ) {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.data.array;\n\t\t\t\t\t\t\t\t\toffset = attribute.offset;\n\t\t\t\t\t\t\t\t\tstride = attribute.data.stride;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.array;\n\t\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\t\tstride = 3;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor ( var i = offset, il = array.length; i < il; i += stride ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromArray( array, i );\n\t\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\t\t point.y < this.min.y || point.y > this.max.y ||\n\t\t\t\t\t point.z < this.min.z || point.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&\n\t\t\t\t ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\t\t box.max.z < this.min.z || box.min.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// 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.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box = new Box3();\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix3( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( (matrix && matrix.isMatrix4) ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.clearColor( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( (light && light.isPointLight) ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( (shadow && shadow.isSpotLightShadow) ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( (material && material.isMultiMaterial) ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: Object3DIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function(){}; \n\t\tthis.onAfterRender = function(){};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype, {\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( (object && object.isObject3D) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\tvar count$2 = 0;\n\tfunction Object3DIdCount() { return count$2++; }\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int16Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint16Array( array ), itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int32Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float64Array( array ), itemSize );\n\n\t}\n\n\t// Deprecated\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [ [] ];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype, {\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( (geometry && geometry.isGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( (mesh && mesh.isMesh) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\tvar dupIndex = - 1;\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tdupIndex = n;\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [ [] ];\n\t\t\tthis.colors = [];\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( var i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( var i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( var k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tvar count$3 = 0;\n\tfunction GeometryIdCount() { return count$3++; }\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'DirectGeometry';\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tcomputeBoundingBox: Geometry.prototype.computeBoundingBox,\n\t\tcomputeBoundingSphere: Geometry.prototype.computeBoundingSphere,\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tthis.index = index;\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( (attribute && attribute.isBufferAttribute) === false && (attribute && attribute.isInterleavedBufferAttribute) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToVector3Array( position.array );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToVector3Array( normal.array );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isPoints) || (object && object.isLine) ) {\n\n\t\t\t\tvar positions = new Float32Attribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32Attribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32Attribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( (object && object.isMesh) ) {\n\n\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isMesh) ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32Attribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32Attribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar positions = this.attributes.position.array;\n\n\t\t\tif ( positions !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromArray( positions );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar positions = this.attributes.position;\n\n\t\t\t\tif ( positions ) {\n\n\t\t\t\t\tvar array = positions.array;\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromArray( array );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i += 3 ) {\n\n\t\t\t\t\t\tvector.fromArray( array, i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC,\n\n\t\t\t\tpA = new Vector3(),\n\t\t\t\tpB = new Vector3(),\n\t\t\t\tpC = new Vector3(),\n\n\t\t\t\tcb = new Vector3(),\n\t\t\t\tab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( (geometry && geometry.isBufferGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {\n\n\t\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\t\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\t\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar uvs, intersection;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( attributes.uv !== undefined ) {\n\n\t\t\t\t\t\tuvs = attributes.uv.array;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = indices[ i ];\n\t\t\t\t\t\t\tb = indices[ i + 1 ];\n\t\t\t\t\t\t\tc = indices[ i + 2 ];\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length; i < l; i += 9 ) {\n\n\t\t\t\t\t\t\ta = i / 3;\n\t\t\t\t\t\t\tb = a + 1;\n\t\t\t\t\t\t\tc = a + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = (material && material.isMultiMaterial);\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );\n\t\tvar indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\t\tvar numberOfVertices = 0;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount( w, h, d ) {\n\n\t\t\tvar vertices = 0;\n\n\t\t\t// calculate the amount of vertices for each side (plane)\n\t\t\tvertices += (w + 1) * (h + 1) * 2; // xy\n\t\t\tvertices += (w + 1) * (d + 1) * 2; // xz\n\t\t\tvertices += (d + 1) * (h + 1) * 2; // zy\n\n\t\t\treturn vertices;\n\n\t\t}\n\n\t\tfunction calculateIndexCount( w, h, d ) {\n\n\t\t\tvar index = 0;\n\n\t\t\t// calculate the amount of squares for each side\n\t\t\tindex += w * h * 2; // xy\n\t\t\tindex += w * d * 2; // xz\n\t\t\tindex += d * h * 2; // zy\n\n\t\t\treturn index * 6; // two triangles per square => six vertices per square\n\n\t\t}\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth\t= width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\t\t\t\t\tvertices[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\t\t\t\t\tnormals[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tnormals[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tnormals[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// uvs\n\t\t\t\t\tuvs[ uvBufferOffset ] = ix / gridX;\n\t\t\t\t\tuvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\t\tuvBufferOffset += 2;\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\t// indices\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tindexBufferOffset += 6;\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar vertices = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar normals = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar uvs = new Float32Array( gridX1 * gridY1 * 2 );\n\n\t\tvar offset = 0;\n\t\tvar offset2 = 0;\n\n\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices[ offset ] = x;\n\t\t\t\tvertices[ offset + 1 ] = - y;\n\n\t\t\t\tnormals[ offset + 2 ] = 1;\n\n\t\t\t\tuvs[ offset2 ] = ix / gridX;\n\t\t\t\tuvs[ offset2 + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\toffset += 3;\n\t\t\t\toffset2 += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\toffset = 0;\n\n\t\tvar indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );\n\n\t\tfor ( var iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( var ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices[ offset ] = a;\n\t\t\t\tindices[ offset + 1 ] = b;\n\t\t\t\tindices[ offset + 2 ] = d;\n\n\t\t\t\tindices[ offset + 3 ] = b;\n\t\t\t\tindices[ offset + 4 ] = c;\n\t\t\t\tindices[ offset + 5 ] = d;\n\n\t\t\t\toffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makeFrustum(\n\t\t\t\t\tleft, left + width, top - height, top, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( (position && position.isInterleavedBufferAttribute) ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( 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\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( (map && map.isTexture) ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( (map && map.isWebGLRenderTarget) ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\t\t\tvar position = attributes.position;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar edges = {};\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;\n\t\t\tvar attribute = new BufferAttribute( new TypeArray( indices ), 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true;\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true;\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( (renderTarget && renderTarget.isWebGLRenderTargetCube) ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = (texture && texture.isCompressedTexture);\n\t\t\t\t\tvar isDataTexture = (texture.image[ 0 ] && texture.image[ 0 ].isDataTexture);\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( (texture && texture.isDepthTexture) ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( (texture && texture.isDataTexture) ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( (texture && texture.isCompressedTexture) ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( (renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture) ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a ) {\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tclearColor( 0, 0, 0, 1 );\n\t\t\tclearDepth( 1 );\n\t\t\tclearStencil( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tgl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction clearColor( r, g, b, a ) {\n\n\t\t\tcolorBuffer.setClear( r, g, b, a );\n\n\t\t}\n\n\t\tfunction clearDepth( depth ) {\n\n\t\t\tdepthBuffer.setClear( depth );\n\n\t\t}\n\n\t\tfunction clearStencil( stencil ) {\n\n\t\t\tstencilBuffer.setClear( stencil );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tclearColor: clearColor,\n\t\t\tclearDepth: clearDepth,\n\t\t\tclearStencil: clearStencil,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t// internal state cache\n\n\t\t_currentProgram = null,\n\t\t_currentRenderTarget = null,\n\t\t_currentFramebuffer = null,\n\t\t_currentMaterialId = - 1,\n\t\t_currentGeometryProgram = '',\n\t\t_currentCamera = null,\n\n\t\t_currentScissor = new Vector4(),\n\t\t_currentScissorTest = null,\n\n\t\t_currentViewport = new Vector4(),\n\n\t\t//\n\n\t\t_usedTextureUnits = 0,\n\n\t\t//\n\n\t\t_clearColor = new Color( 0x000000 ),\n\t\t_clearAlpha = 0,\n\n\t\t_width = _canvas.width,\n\t\t_height = _canvas.height,\n\n\t\t_pixelRatio = 1,\n\n\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t_scissorTest = false,\n\n\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t// frustum\n\n\t\t_frustum = new Frustum(),\n\n\t\t// clipping\n\n\t\t_clipping = new WebGLClipping(),\n\t\t_clippingEnabled = false,\n\t\t_localClippingEnabled = false,\n\n\t\t_sphere = new Sphere(),\n\n\t\t// camera matrices cache\n\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_vector3 = new Vector3(),\n\n\t\t// light arrays cache\n\n\t\t_lights = {\n\n\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\tshadows: []\n\n\t\t},\n\n\t\t// info\n\n\t\t_infoRender = {\n\n\t\t\tcalls: 0,\n\t\t\tvertices: 0,\n\t\t\tfaces: 0,\n\t\t\tpoints: 0\n\n\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\t\tvar backgroundCamera2 = new PerspectiveCamera();\n\t\tvar backgroundPlaneMesh = new Mesh(\n\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t);\n\t\tvar backgroundBoxShader = ShaderLib[ 'cube' ];\n\t\tvar backgroundBoxMesh = new Mesh(\n\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\tnew ShaderMaterial( {\n\t\t\t\tuniforms: backgroundBoxShader.uniforms,\n\t\t\t\tvertexShader: backgroundBoxShader.vertexShader,\n\t\t\t\tfragmentShader: backgroundBoxShader.fragmentShader,\n\t\t\t\tside: BackSide,\n\t\t\t\tdepthTest: false,\n\t\t\t\tdepthWrite: false,\n\t\t\t\tfog: false\n\t\t\t} )\n\t\t);\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction glClearColor( r, g, b, a ) {\n\n\t\t\tif ( _premultipliedAlpha === true ) {\n\n\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t}\n\n\t\t\tstate.clearColor( r, g, b, a );\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t ! material.isMeshStandardMaterial &&\n\t\t\t\t material.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar type = _gl.FLOAT;\n\t\t\t\t\t\tvar array = geometryAttribute.array;\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\n\t\t\t\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.FLOAT;\n\n\t\t\t\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.BYTE;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_BYTE;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\t\t\t\t\t\tvar buffer = objects.getAttributeBuffer( geometryAttribute );\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tglClearColor( background.r, background.g, background.b, 1 );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tbackgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t ! material.isRawShaderMaterial ||\n\t\t\t material.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes || \n\t \t\t\t\t materialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isShaderMaterial ||\n\t\t\t\t material.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\tm_uniforms.opacity.value = material.opacity;\n\n\t\t\t\t}\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\tr = 0, g = 0, b = 0,\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\tdistance,\n\t\t\tshadowMap,\n\n\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\t p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone( skin ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t\tthis.skin = skin;\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.skin = source.skin;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone( this );\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( (this.geometry && this.geometry.isGeometry) ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.type = type !== undefined ? type : UnsignedShortType;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar numEdges = 0;\n\n\t\t\t// allocate maximal size\n\t\t\tvar edges = new Uint32Array( 6 * faces.length );\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\tvar vertex = vertices[ edges [ 2 * i + j ] ];\n\n\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\tcoords[ index + 0 ] = vertex.x;\n\t\t\t\t\tcoords[ index + 1 ] = vertex.y;\n\t\t\t\t\tcoords[ index + 2 ] = vertex.z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// Indexed BufferGeometry\n\n\t\t\t\tvar indices = geometry.index.array;\n\t\t\t\tvar vertices = geometry.attributes.position;\n\t\t\t\tvar groups = geometry.groups;\n\t\t\t\tvar numEdges = 0;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.length );\n\n\t\t\t\t}\n\n\t\t\t\t// allocate maximal size\n\t\t\t\tvar edges = new Uint32Array( 2 * indices.length );\n\n\t\t\t\tfor ( var o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tvar group = groups[ o ];\n\n\t\t\t\t\tvar start = group.start;\n\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices[ i + j ];\n\t\t\t\t\t\t\tedge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];\n\t\t\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\t\tvar index2 = edges[ 2 * i + j ];\n\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices.getX( index2 );\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices.getY( index2 );\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices.getZ( index2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tvar vertices = geometry.attributes.position.array;\n\t\t\t\tvar numEdges = vertices.length / 3;\n\t\t\t\tvar numTris = numEdges / 3;\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numTris; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\tvar index = 18 * i + 6 * j;\n\n\t\t\t\t\t\tvar index1 = 9 * i + 3 * j;\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices[ index1 ];\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices[ index1 + 1 ];\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices[ index1 + 2 ];\n\n\t\t\t\t\t\tvar index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tcoords[ index + 3 ] = vertices[ index2 ];\n\t\t\t\t\t\tcoords[ index + 4 ] = vertices[ index2 + 1 ];\n\t\t\t\t\t\tcoords[ index + 5 ] = vertices[ index2 + 2 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// generate vertices and uvs\n\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j, p;\n\t\tvar u, v;\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tv = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tu = j / slices;\n\n\t\t\t\tp = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tvar indices = [];\n\t\tvar a, b, c, d;\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\ta = i * sliceCount + j;\n\t\t\t\tb = i * sliceCount + j + 1;\n\t\t\t\tc = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\td = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', Float32Attribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0 ; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols ; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius,detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t *\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar i, j, index = 0, indexOffset = 0;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\tuv.y = j / radialSegments;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\n\t\t// helper variables\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices[ vertexBufferOffset ] = vertex.x;\n\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vertex.y;\n\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vertex.z;\n\n\t\t\t\t// this vector is used to calculate the normal\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\n\t\t\t\t// normal\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals[ vertexBufferOffset ] = normal.x;\n\t\t\t\tnormals[ vertexBufferOffset + 1 ] = normal.y;\n\t\t\t\tnormals[ vertexBufferOffset + 2 ] = normal.z;\n\n\t\t\t\t// uv\n\t\t\t\tuvs[ uvBufferOffset ] = i / tubularSegments;\n\t\t\t\tuvs[ uvBufferOffset + 1 ] = j / radialSegments;\n\n\t\t\t\t// update offsets\n\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\tuvBufferOffset += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t// face two\n\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t// update offset\n\t\t\t\tindexBufferOffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// 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.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t},\n\n\t\t// Bezier Curves formulas obtained from\n\t\t// http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n\t\t// Quad Bezier Functions\n\n\t\tb2: ( function () {\n\n\t\t\tfunction b2p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p1( t, p ) {\n\n\t\t\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p2( t, p ) {\n\n\t\t\t\treturn t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b2( t, p0, p1, p2 ) {\n\n\t\t\t\treturn b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\t// Cubic Bezier Functions\n\n\t\tb3: ( function () {\n\n\t\t\tfunction b3p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p1( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * k * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p2( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * t * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p3( t, p ) {\n\n\t\t\t\treturn t * t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b3( t, p0, p1, p2, p3 ) {\n\n\t\t\t\treturn b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( (font && font.isFont) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * based on THREE.SphereGeometry\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );\n\n\t\tvar positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\tvar index = 0, vertices = [], normal = new Vector3();\n\n\t\tfor ( var y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = y / heightSegments;\n\n\t\t\tfor ( var x = 0; x <= widthSegments; x ++ ) {\n\n\t\t\t\tvar u = x / widthSegments;\n\n\t\t\t\tvar px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvar py = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvar pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tnormal.set( px, py, pz ).normalize();\n\n\t\t\t\tpositions.setXYZ( index, px, py, pz );\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\tverticesRow.push( index );\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tvertices.push( verticesRow );\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var y = 0; y < heightSegments; y ++ ) {\n\n\t\t\tfor ( var x = 0; x < widthSegments; x ++ ) {\n\n\t\t\t\tvar v1 = vertices[ y ][ x + 1 ];\n\t\t\t\tvar v2 = vertices[ y ][ x ];\n\t\t\t\tvar v3 = vertices[ y + 1 ][ x ];\n\t\t\t\tvar v4 = vertices[ y + 1 ][ x + 1 ];\n\n\t\t\t\tif ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );\n\t\t\t\tif ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', positions );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 );\n\t\tvar indexCount = thetaSegments * phiSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// some helper variables\n\t\tvar index = 0, indexOffset = 0, segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\t// values are generate from the inside of the ring to the outside\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, 0, 1 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex++;\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\t // points - to create a closed torus, one must use a set of points\n\t // like so: [ a, b, c, d, a ], see first is the same as last.\n\t // segments - the number of circumference segments to create\n\t // phiStart - the starting radian\n\t // phiLength - the radian (0 to 2PI) range of the lathed section\n\t // 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( segments + 1 ) * points.length;\n\t\tvar indexCount = segments * points.length * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar index = 0, indexOffset = 0, base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t} // next row\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t *\n\t * Creates a one-sided polygonal geometry from a path shape. Similar to\n\t * ExtrudeGeometry.\n\t *\n\t * parameters = {\n\t *\n\t *\tcurveSegments: , // number of points on the curves. NOT USED AT THE MOMENT.\n\t *\n\t *\tmaterial: // material index for front and back faces\n\t *\tuvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ShapeGeometry( shapes, options ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( Array.isArray( shapes ) === false ) shapes = [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * Add an array of shapes to THREE.ShapeGeometry.\n\t */\n\tShapeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tfor ( var i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tthis.addShape( shapes[ i ], options );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.\n\t */\n\tShapeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tif ( options === undefined ) options = {};\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar material = options.material;\n\t\tvar uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;\n\n\t\t//\n\n\t\tvar i, l, hole;\n\n\t\tvar shapesOffset = this.vertices.length;\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe...\n\n\t\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\t\thole = holes[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( hole ) ) {\n\n\t\t\t\t\tholes[ i ] = hole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false;\n\n\t\t}\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t// Vertices\n\n\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\thole = holes[ i ];\n\t\t\tvertices = vertices.concat( hole );\n\n\t\t}\n\n\t\t//\n\n\t\tvar vert, vlen = vertices.length;\n\t\tvar face, flen = faces.length;\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = vertices[ i ];\n\n\t\t\tthis.vertices.push( new Vector3( vert.x, vert.y, 0 ) );\n\n\t\t}\n\n\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\tface = faces[ i ];\n\n\t\t\tvar a = face[ 0 ] + shapesOffset;\n\t\t\tvar b = face[ 1 ] + shapesOffset;\n\t\t\tvar c = face[ 2 ] + shapesOffset;\n\n\t\t\tthis.faces.push( new Face3( a, b, c, null, null, material ) );\n\t\t\tthis.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tvar geometry2;\n\n\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar vertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tvar key = edge.toString();\n\n\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\thash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\thash[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar coords = [];\n\n\t\tfor ( var key in hash ) {\n\n\t\t\tvar h = hash[ key ];\n\n\t\t\tif ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = vertices[ h.vert1 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t\tvertex = vertices[ h.vert2 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) );\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// used to calculate buffer length\n\n\t\tvar nbCap = 0;\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) nbCap ++;\n\t\t\tif ( radiusBottom > 0 ) nbCap ++;\n\n\t\t}\n\n\t\tvar vertexCount = calculateVertexCount();\n\t\tvar indexCount = calculateIndexCount();\n\n\t\t// buffers\n\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\n\t\tvar index = 0,\n\t\t indexOffset = 0,\n\t\t indexArray = [],\n\t\t halfHeight = height / 2;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount() {\n\n\t\t\tvar count = ( radialSegments + 1 ) * ( heightSegments + 1 );\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap );\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction calculateIndexCount() {\n\n\t\t\tvar count = radialSegments * heightSegments * 2 * 3;\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += radialSegments * nbCap * 3;\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\t\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\t\t\t\t\tindexRow.push( index );\n\n\t\t\t\t\t// increase index\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\tvar i1 = indexArray[ y ][ x ];\n\t\t\t\t\tvar i2 = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar i3 = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar i4 = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices.setX( indexOffset, i1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i3 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// update counters\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = 0.5;\n\t\t\t\tuv.y = 0.5;\n\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t}\n\n\t\t\t\t// update counters\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tvar vertices = segments + 2;\n\n\t\tvar positions = new Float32Array( vertices * 3 );\n\t\tvar normals = new Float32Array( vertices * 3 );\n\t\tvar uvs = new Float32Array( vertices * 2 );\n\n\t\t// center data is already zero, but need to set a few extras\n\t\tnormals[ 2 ] = 1.0;\n\t\tuvs[ 0 ] = 0.5;\n\t\tuvs[ 1 ] = 0.5;\n\n\t\tfor ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\tpositions[ i ] = radius * Math.cos( segment );\n\t\t\tpositions[ i + 1 ] = radius * Math.sin( segment );\n\n\t\t\tnormals[ i + 2 ] = 1; // normal z\n\n\t\t\tuvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;\n\t\t\tuvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry,\n\t\tBoxGeometry: BoxGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib[ \"lights\" ],\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = materials instanceof Array ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction XHRLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( XHRLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[1];\n\t\t\t\tvar isBase64 = !!dataUriRegexResult[2];\n\t\t\t\tvar data = dataUriRegexResult[3];\n\n\t\t\t\tdata = window.decodeURIComponent(data);\n\n\t\t\t\tif( isBase64 ) {\n\t\t\t\t\tdata = window.atob(data);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { \"type\" : mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tvar DataTextureLoader = BinaryTextureLoader;\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( BinaryTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\t\t\timage.onload = function () {\n\n\t\t\t\timage.onload = null;\n\n\t\t\t\tURL.revokeObjectURL( image.src );\n\n\t\t\t\tif ( onLoad ) onLoad( image );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t};\n\t\t\timage.onerror = onError;\n\n\t\t\tif ( url.indexOf( 'data:' ) === 0 ) {\n\n\t\t\t\timage.src = url;\n\n\t\t\t} else {\n\n\t\t\t\tvar loader = new XHRLoader();\n\t\t\t\tloader.setPath( this.path );\n\t\t\t\tloader.setResponseType( 'blob' );\n\t\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\t\tloader.load( url, function ( blob ) {\n\n\t\t\t\t\timage.src = URL.createObjectURL( blob );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( light ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true,\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function() {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function() {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function( timeOffset ) {\n\n\t\t\tif( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function( timeScale ) {\n\n\t\t\tif( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== -1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to , 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function() {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function() {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number',\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max(\n\t\t\t\t\t\tduration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0;\n\t\t\t\t\t\t\t\tm !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack(\n\t\t\t\t\t\t\t\t'.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader ( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tscope.parse( JSON.parse( text ), onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.SplineCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = 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\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\t// TODO: Transformation for Curves?\n\n\t/**************************************************************\n\t *\t3D Curves\n\t **************************************************************/\n\n\t// A Factory method for creating new curve subclasses\n\n\tCurve.create = function ( constructor, getPointFunc ) {\n\n\t\tconstructor.prototype = Object.create( Curve.prototype );\n\t\tconstructor.prototype.constructor = constructor;\n\t\tconstructor.prototype.getPoint = getPointFunc;\n\n\t\treturn constructor;\n\n\t};\n\n\t/**************************************************************\n\t *\tLine\n\t **************************************************************/\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**************************************************************\n\t *\tEllipse curve\n\t **************************************************************/\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar CurveUtils = {\n\n\t\ttangentQuadraticBezier: function ( t, p0, p1, p2 ) {\n\n\t\t\treturn 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );\n\n\t\t},\n\n\t\t// Puay Bing, thanks for helping with this derivative!\n\n\t\ttangentCubicBezier: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\treturn - 3 * p0 * ( 1 - t ) * ( 1 - t ) +\n\t\t\t\t3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +\n\t\t\t\t6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +\n\t\t\t\t3 * t * t * p3;\n\n\t\t},\n\n\t\ttangentSpline: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\t// To check if my formulas are correct\n\n\t\t\tvar h00 = 6 * t * t - 6 * t; \t// derived from 2t^3 − 3t^2 + 1\n\t\t\tvar h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t\n\t\t\tvar h01 = - 6 * t * t + 6 * t; \t// − 2t3 + 3t2\n\t\t\tvar h11 = 3 * t * t - 2 * t;\t// t3 − t2\n\n\t\t\treturn h00 + h10 + h01 + h11;\n\n\t\t},\n\n\t\t// Catmull-Rom\n\n\t\tinterpolate: function( p0, p1, p2, p3, t ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t * t2;\n\t\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t};\n\n\t/**************************************************************\n\t *\tSpline curve\n\t **************************************************************/\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\treturn new Vector2(\n\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight )\n\t\t);\n\n\t};\n\n\t/**************************************************************\n\t *\tCubic Bezier curve\n\t **************************************************************/\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b3 = ShapeUtils.b3;\n\n\t\treturn new Vector2(\n\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t);\n\n\t};\n\n\tCubicBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentCubicBezier = CurveUtils.tangentCubicBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\ttangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t).normalize();\n\n\t};\n\n\t/**************************************************************\n\t *\tQuadratic Bezier curve\n\t **************************************************************/\n\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b2 = ShapeUtils.b2;\n\n\t\treturn new Vector2(\n\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t);\n\n\t};\n\n\n\tQuadraticBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\ttangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t).normalize();\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t *\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\n\t// minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\tfunction ShapePath() {\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\t}\n\n\tShapePath.prototype = {\n\t\tmoveTo: function ( x, y ) {\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push(this.currentPath);\n\t\t\tthis.currentPath.moveTo( x, y );\n\t\t},\n\t\tlineTo: function ( x, y ) {\n\t\t\tthis.currentPath.lineTo( x, y );\n\t\t},\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\t\t},\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\t\t},\n\t\tsplineThru: function ( pts ) {\n\t\t\tthis.currentPath.splineThru( pts );\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar offset = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar ret = createPath( chars[ i ], scale, offset );\n\t\t\t\t\toffset += ret.offset;\n\n\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offset ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3;\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb2( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tb2( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb3( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tb3( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offset: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tfunction getAudioContext() {\n\n\t\tif ( context === undefined ) {\n\n\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn context;\n\n\t}\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = getAudioContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = getAudioContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\t\tthis.source = this.context.createBufferSource();\n\t\tthis.source.onended = this.onEnded.bind( this );\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.source.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.source.buffer;\n\t\t\tsource.loop = this.source.loop;\n\t\t\tsource.onended = this.source.onended;\n\t\t\tsource.start( 0, this.startTime );\n\t\t\tsource.playbackRate.value = this.playbackRate;\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.value = this.playbackRate;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.source.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.loop = value;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\t\t\tmixFunction = this._slerp;\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\n\t\t\t\tbufferType = Array,\t\tmixFunction = this._select;\t\tbreak;\n\n\t\t\tdefault:\t\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( (root && root.isAnimationObjectGroup) ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:\\w+[\\/:])*)(\\w+)?(?:\\.(\\w+)(?:\\[(.+)\\])?)?\\.(\\w+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tvar knownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis.loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype, {\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function() {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function() {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function() {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function() {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Spline from Tween.js, slightly optimized (and trashed)\n\t * http://sole.github.com/tween.js/examples/05_spline.html\n\t *\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Spline( points ) {\n\n\t\tthis.points = points;\n\n\t\tvar c = [], v3 = { x: 0, y: 0, z: 0 },\n\t\tpoint, intPoint, weight, w2, w3,\n\t\tpa, pb, pc, pd;\n\n\t\tthis.initFromArray = function ( a ) {\n\n\t\t\tthis.points = [];\n\n\t\t\tfor ( var i = 0; i < a.length; i ++ ) {\n\n\t\t\t\tthis.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getPoint = function ( k ) {\n\n\t\t\tpoint = ( this.points.length - 1 ) * k;\n\t\t\tintPoint = Math.floor( point );\n\t\t\tweight = point - intPoint;\n\n\t\t\tc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;\n\t\t\tc[ 1 ] = intPoint;\n\t\t\tc[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;\n\t\t\tc[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;\n\n\t\t\tpa = this.points[ c[ 0 ] ];\n\t\t\tpb = this.points[ c[ 1 ] ];\n\t\t\tpc = this.points[ c[ 2 ] ];\n\t\t\tpd = this.points[ c[ 3 ] ];\n\n\t\t\tw2 = weight * weight;\n\t\t\tw3 = weight * w2;\n\n\t\t\tv3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );\n\t\t\tv3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );\n\t\t\tv3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );\n\n\t\t\treturn v3;\n\n\t\t};\n\n\t\tthis.getControlPointsArray = function () {\n\n\t\t\tvar i, p, l = this.points.length,\n\t\t\t\tcoords = [];\n\n\t\t\tfor ( i = 0; i < l; i ++ ) {\n\n\t\t\t\tp = this.points[ i ];\n\t\t\t\tcoords[ i ] = [ p.x, p.y, p.z ];\n\n\t\t\t}\n\n\t\t\treturn coords;\n\n\t\t};\n\n\t\t// approximate length by summing linear segments\n\n\t\tthis.getLength = function ( nSubDivisions ) {\n\n\t\t\tvar i, index, nSamples, position,\n\t\t\t\tpoint = 0, intPoint = 0, oldIntPoint = 0,\n\t\t\t\toldPosition = new Vector3(),\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tchunkLengths = [],\n\t\t\t\ttotalLength = 0;\n\n\t\t\t// first point has 0 length\n\n\t\t\tchunkLengths[ 0 ] = 0;\n\n\t\t\tif ( ! nSubDivisions ) nSubDivisions = 100;\n\n\t\t\tnSamples = this.points.length * nSubDivisions;\n\n\t\t\toldPosition.copy( this.points[ 0 ] );\n\n\t\t\tfor ( i = 1; i < nSamples; i ++ ) {\n\n\t\t\t\tindex = i / nSamples;\n\n\t\t\t\tposition = this.getPoint( index );\n\t\t\t\ttmpVec.copy( position );\n\n\t\t\t\ttotalLength += tmpVec.distanceTo( oldPosition );\n\n\t\t\t\toldPosition.copy( position );\n\n\t\t\t\tpoint = ( this.points.length - 1 ) * index;\n\t\t\t\tintPoint = Math.floor( point );\n\n\t\t\t\tif ( intPoint !== oldIntPoint ) {\n\n\t\t\t\t\tchunkLengths[ intPoint ] = totalLength;\n\t\t\t\t\toldIntPoint = intPoint;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// last point ends with total length\n\n\t\t\tchunkLengths[ chunkLengths.length ] = totalLength;\n\n\t\t\treturn { chunks: chunkLengths, total: totalLength };\n\n\t\t};\n\n\t\tthis.reparametrizeByArcLength = function ( samplingCoef ) {\n\n\t\t\tvar i, j,\n\t\t\t\tindex, indexCurrent, indexNext,\n\t\t\t\trealDistance,\n\t\t\t\tsampling, position,\n\t\t\t\tnewpoints = [],\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tsl = this.getLength();\n\n\t\t\tnewpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );\n\n\t\t\tfor ( i = 1; i < this.points.length; i ++ ) {\n\n\t\t\t\t//tmpVec.copy( this.points[ i - 1 ] );\n\t\t\t\t//linearDistance = tmpVec.distanceTo( this.points[ i ] );\n\n\t\t\t\trealDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];\n\n\t\t\t\tsampling = Math.ceil( samplingCoef * realDistance / sl.total );\n\n\t\t\t\tindexCurrent = ( i - 1 ) / ( this.points.length - 1 );\n\t\t\t\tindexNext = i / ( this.points.length - 1 );\n\n\t\t\t\tfor ( j = 1; j < sampling - 1; j ++ ) {\n\n\t\t\t\t\tindex = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );\n\n\t\t\t\t\tposition = this.getPoint( index );\n\t\t\t\t\tnewpoints.push( tmpVec.copy( position ).clone() );\n\n\t\t\t\t}\n\n\t\t\t\tnewpoints.push( tmpVec.copy( this.points[ i ] ).clone() );\n\n\t\t\t}\n\n\t\t\tthis.points = newpoints;\n\n\t\t};\n\n\t\t// Catmull-Rom\n\n\t\tfunction interpolate( p0, p1, p2, p3, t, t2, t3 ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5,\n\t\t\t\tv1 = ( p3 - p1 ) * 0.5;\n\n\t\t\treturn ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new Geometry();\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.colors.push( new Color( 0, 0, 1 ) );\n\t\t\t\tgeometry.colors.push( new Color( 0, 1, 0 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.dynamic = true;\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( (object && object.isBone) ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar geometry = this.geometry;\n\n\t\tvar matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld );\n\n\t\tvar boneMatrix = new Matrix4();\n\n\t\tvar j = 0;\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\tgeometry.vertices[ j ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\tgeometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.verticesNeedUpdate = true;\n\n\t\tgeometry.computeBoundingSphere();\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction HemisphereLightHelper( light, sphereSize ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.colors = [ new Color(), new Color() ];\n\n\t\tvar geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tgeometry.rotateX( - Math.PI / 2 );\n\n\t\tfor ( var i = 0, il = 8; i < il; i ++ ) {\n\n\t\t\tgeometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];\n\n\t\t}\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } );\n\n\t\tthis.lightSphere = new Mesh( geometry, material );\n\t\tthis.add( this.lightSphere );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.lightSphere.geometry.dispose();\n\t\tthis.lightSphere.material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tthis.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tthis.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tthis.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\t\t\tthis.lightSphere.geometry.colorsNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tdivisions = divisions || 1;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = ( size * 2 ) / divisions;\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - size, 0, k, size, 0, k );\n\t\t\tvertices.push( k, 0, - size, k, 0, size );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new Geometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar hexFrustum = 0xffaa00;\n\t\tvar hexCone = 0xff0000;\n\t\tvar hexUp = 0x00aaff;\n\t\tvar hexTarget = 0xffffff;\n\t\tvar hexCross = 0x333333;\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", hexFrustum );\n\t\taddLine( \"n2\", \"n4\", hexFrustum );\n\t\taddLine( \"n4\", \"n3\", hexFrustum );\n\t\taddLine( \"n3\", \"n1\", hexFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", hexFrustum );\n\t\taddLine( \"f2\", \"f4\", hexFrustum );\n\t\taddLine( \"f4\", \"f3\", hexFrustum );\n\t\taddLine( \"f3\", \"f1\", hexFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", hexFrustum );\n\t\taddLine( \"n2\", \"f2\", hexFrustum );\n\t\taddLine( \"n3\", \"f3\", hexFrustum );\n\t\taddLine( \"n4\", \"f4\", hexFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", hexCone );\n\t\taddLine( \"p\", \"n2\", hexCone );\n\t\taddLine( \"p\", \"n3\", hexCone );\n\t\taddLine( \"p\", \"n4\", hexCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", hexUp );\n\t\taddLine( \"u2\", \"u3\", hexUp );\n\t\taddLine( \"u3\", \"u1\", hexUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", hexTarget );\n\t\taddLine( \"p\", \"c\", hexCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", hexCross );\n\t\taddLine( \"cn3\", \"cn4\", hexCross );\n\n\t\taddLine( \"cf1\", \"cf2\", hexCross );\n\t\taddLine( \"cf3\", \"cf4\", hexCross );\n\n\t\tfunction addLine( a, b, hex ) {\n\n\t\t\taddPoint( a, hex );\n\t\t\taddPoint( b, hex );\n\n\t\t}\n\n\t\tfunction addPoint( id, hex ) {\n\n\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\tgeometry.colors.push( new Color( hex ) );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( geometry.vertices.length - 1 );\n\n\t\t}\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tgeometry.vertices[ points[ i ] ].copy( vector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.verticesNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\t// a helper to show the world-axis-aligned bounding box for an object\n\n\tfunction BoundingBoxHelper( object, hex ) {\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0x888888;\n\n\t\tthis.object = object;\n\n\t\tthis.box = new Box3();\n\n\t\tMesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) );\n\n\t}\n\n\tBoundingBoxHelper.prototype = Object.create( Mesh.prototype );\n\tBoundingBoxHelper.prototype.constructor = BoundingBoxHelper;\n\n\tBoundingBoxHelper.prototype.update = function () {\n\n\t\tthis.box.setFromObject( this.object );\n\n\t\tthis.box.getSize( this.scale );\n\n\t\tthis.box.getCenter( this.position );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar 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 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( (object && object.isBox3) ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry = new BufferGeometry();\n\tlineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\tvar coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = new Float32Array( [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t] );\n\n\t\tvar colors = new Float32Array( [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t] );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\tvar CatmullRomCurve3 = ( function() {\n\n\t\tvar\n\t\t\ttmp = new Vector3(),\n\t\t\tpx = new CubicPoly(),\n\t\t\tpy = new CubicPoly(),\n\t\t\tpz = new CubicPoly();\n\n\t\t/*\n\t\tBased on an optimized c++ solution in\n\t\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t\t - http://ideone.com/NoEbVM\n\n\t\tThis CubicPoly class could be used for reusing some variables and calculations,\n\t\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\t\twhich can be placed in CurveUtils.\n\t\t*/\n\n\t\tfunction CubicPoly() {}\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tCubicPoly.prototype.init = function( x0, x1, t0, t1 ) {\n\n\t\t\tthis.c0 = x0;\n\t\t\tthis.c1 = t0;\n\t\t\tthis.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tthis.c3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t};\n\n\t\tCubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\t// initCubicPoly\n\t\t\tthis.init( x1, x2, t1, t2 );\n\n\t\t};\n\n\t\t// standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4\n\t\tCubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {\n\n\t\t\tthis.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t};\n\n\t\tCubicPoly.prototype.calc = function( t ) {\n\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t2 * t;\n\t\t\treturn this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;\n\n\t\t};\n\n\t\t// Subclass Three.js curve\n\t\treturn Curve.create(\n\n\t\t\tfunction ( p /* array of Vector3 */ ) {\n\n\t\t\t\tthis.points = p || [];\n\t\t\t\tthis.closed = false;\n\n\t\t\t},\n\n\t\t\tfunction ( t ) {\n\n\t\t\t\tvar points = this.points,\n\t\t\t\t\tpoint, intPoint, weight, l;\n\n\t\t\t\tl = points.length;\n\n\t\t\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\t\t\tpoint = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\t\t\tintPoint = Math.floor( point );\n\t\t\t\tweight = point - intPoint;\n\n\t\t\t\tif ( this.closed ) {\n\n\t\t\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\t\t\tintPoint = l - 2;\n\t\t\t\t\tweight = 1;\n\n\t\t\t\t}\n\n\t\t\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\t\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate first point\n\t\t\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\t\t\tp0 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tp1 = points[ intPoint % l ];\n\t\t\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\t\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate last point\n\t\t\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\t\t\tp3 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t\t\t// safety check for repeated points\n\t\t\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t\t\t}\n\n\t\t\t\tvar v = new Vector3(\n\t\t\t\t\tpx.calc( weight ),\n\t\t\t\t\tpy.calc( weight ),\n\t\t\t\t\tpz.calc( weight )\n\t\t\t\t);\n\n\t\t\t\treturn v;\n\n\t\t\t}\n\n\t\t);\n\n\t} )();\n\n\t/**************************************************************\n\t *\tClosed Spline 3D curve\n\t **************************************************************/\n\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t/**************************************************************\n\t *\tSpline 3D curve\n\t **************************************************************/\n\n\n\tvar SplineCurve3 = Curve.create(\n\n\t\tfunction ( points /* array of Vector3 */ ) {\n\n\t\t\tconsole.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );\n\t\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar points = this.points;\n\t\t\tvar point = ( points.length - 1 ) * t;\n\n\t\t\tvar intPoint = Math.floor( point );\n\t\t\tvar weight = point - intPoint;\n\n\t\t\tvar point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];\n\t\t\tvar point1 = points[ intPoint ];\n\t\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\t\treturn new Vector3(\n\t\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight ),\n\t\t\t\tinterpolate( point0.z, point1.z, point2.z, point3.z, weight )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tCubic Bezier 3D curve\n\t **************************************************************/\n\n\tvar CubicBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2, v3 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\t\t\tthis.v3 = v3;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b3 = ShapeUtils.b3;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),\n\t\t\t\tb3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tQuadratic Bezier 3D curve\n\t **************************************************************/\n\n\tvar QuadraticBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b2 = ShapeUtils.b2;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y ),\n\t\t\t\tb2( t, this.v0.z, this.v1.z, this.v2.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tLine3D\n\t **************************************************************/\n\n\tvar LineCurve3 = Curve.create(\n\n\t\tfunction ( v1, v2 ) {\n\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tif ( t === 1 ) {\n\n\t\t\t\treturn this.v2.clone();\n\n\t\t\t}\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\t\tvector.multiplyScalar( t );\n\t\t\tvector.add( this.v1 );\n\n\t\t\treturn vector;\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tArc curve\n\t **************************************************************/\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4 ( a, b, c, d, normal, color, materialIndex ) {\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction PointCloud ( geometry, material ) {\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction ParticleSystem ( geometry, material ) {\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction PointCloudMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleBasicMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleSystemMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction Vertex ( x, y, z ) {\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\t}\n\n\t//\n\n\tfunction EdgesHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\tfunction WireframeHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Line3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix3.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\t\textractPosition: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\t\t},\n\t\tsetRotationFromQuaternion: function ( q ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );\n\t\t\treturn vector.applyProjection( this );\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t},\n\t\trotateAxis: function ( v ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\ttranslate: function ( v ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\t\t},\n\t\trotateX: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\t\t},\n\t\trotateY: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\t\t},\n\t\trotateZ: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\t\t},\n\t\trotateByAxis: function ( axis, angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.assign( Plane.prototype, {\n\t\tisIntersectionLine: function ( line ) {\n\t\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\t\treturn this.intersectsLine( line );\n\t\t}\n\t} );\n\n\tObject.assign( Quaternion.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\t\treturn vector.applyQuaternion( this );\n\t\t}\n\t} );\n\n\tObject.assign( Ray.prototype, {\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t}\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\t\textrude: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\t\t}\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\t\tsetEulerFromRotationMatrix: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Object3D.prototype, {\n\t\tgetChildByName: function ( name ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\t\t},\n\t\trenderDepth: function ( value ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\t\t}\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\t\teulerOrder: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\t\tobjects: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\t\tlength: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );\n\t\t\t\treturn this.array.length;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\t\taddIndex: function ( index ) {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\t\t\tif ( indexOffset !== undefined ) {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\t\t},\n\t\tclearDrawCalls: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\t\t},\n\t\tcomputeTangents: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\t\t},\n\t\tcomputeOffsets: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\t\twrapAround: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\t\tmetal: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\t\tderivatives: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tEventDispatcher.prototype = Object.assign( Object.create( {\n\n\t\t// Note: Extra base ensures these properties are not 'assign'ed.\n\n\t\tconstructor: EventDispatcher,\n\n\t\tapply: function ( target ) {\n\n\t\t\tconsole.warn( \"THREE.EventDispatcher: .apply is deprecated, \" +\n\t\t\t\t\t\"just inherit or Object.assign the prototype to mix-in.\" );\n\n\t\t\tObject.assign( target, this );\n\n\t\t}\n\n\t} ), EventDispatcher.prototype );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\t\tdynamic: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\t\tsupportsFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\t\t\treturn this.capabilities.vertexTextures;\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\t\t},\n\t\tinitMaterial: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\t\t},\n\t\taddPrePlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\t\t},\n\t\taddPostPlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\t\t},\n\t\tupdateShadowMap: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.enabled;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.cullFace;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\t\tcullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\t\twrapS: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Audio.prototype, {\n\t\tload: function ( file ) {\n\t\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' );\n\t\t\tvar scope = this;\n\t\t\tvar audioLoader = new AudioLoader();\n\t\t\taudioLoader.load( file, function ( buffer ) {\n\t\t\t\tscope.setBuffer( buffer );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\t} );\n\n\tObject.assign( AudioAnalyser.prototype, {\n\t\tgetData: function ( file ) {\n\t\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\t\treturn this.getFrequencyData();\n\t\t}\n\t} );\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector () {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function ( vector, camera ) {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer () {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.TextureIdCount = TextureIdCount;\n\texports.Texture = Texture;\n\texports.MaterialIdCount = MaterialIdCount;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.XHRLoader = XHRLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.getAudioContext = getAudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3DIdCount = Object3DIdCount;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Spline = Spline;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.ColorKeywords = ColorKeywords;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.ShapePath = ShapePath;\n\texports.Path = Path;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.CurveUtils = CurveUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.BlendingMode = BlendingMode;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.TextureMapping = TextureMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.TextureWrapping = TextureWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.TextureFilter = TextureFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MultiMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Sprite;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n\tObject.defineProperty( exports, 'AudioContext', {\n\t\tget: function () {\n\t\t\treturn exports.getAudioContext();\n\t\t}\n\t});\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 2\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/silver-3da470.bmp\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/silver.bmp\n// module id = 3\n// module chunks = 0","\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\nimport Stats from 'stats-js'\r\nimport DAT from 'dat-gui'\r\n\r\n// when the scene is done initializing, the function passed as `callback` will be executed\r\n// then, every frame, the function passed as `update` will be executed\r\nfunction init(callback, update) {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var gui = new DAT.GUI({autoPlace: false});\r\n\r\n\r\n var framework = {\r\n gui: gui,\r\n stats: stats\r\n };\r\n\r\n // run this function after the window loads\r\n window.addEventListener('load', function() {\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x020202, 0);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.target.set(0, 0, 0);\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n controls.addEventListener('change', function() {\r\n camera.hasMoved = true;\r\n });\r\n\r\n document.body.appendChild(renderer.domElement);\r\n\r\n // resize the canvas when the window changes\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n }, false);\r\n\r\n // assign THREE.js objects to the object we will return\r\n framework.scene = scene;\r\n framework.camera = camera;\r\n framework.renderer = renderer;\r\n\r\n // begin the animation loop\r\n (function tick() {\r\n stats.begin();\r\n update(framework); // perform any requested updates\r\n renderer.render(scene, camera); // render the scene\r\n stats.end();\r\n requestAnimationFrame(tick); // register to call this again when the browser renders a new frame\r\n })();\r\n\r\n // we will pass the scene, gui, renderer, camera, etc... to the callback function\r\n return callback(framework);\r\n });\r\n}\r\n\r\nexport default {\r\n init: init\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/framework.js","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 5\n// module chunks = 0","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 6\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n height: 1em;\\n border-radius: 1em;\\n background-color: #eee;\\n padding: 0 0.5em;\\n overflow: hidden;\\n}\\n\\n.slider-fg {\\n padding: 1px 0 2px 0;\\n background-color: #aaa;\\n height: 1em;\\n margin-left: -0.5em;\\n padding-right: 0.5em;\\n border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n display: inline-block;\\n border-radius: 1em;\\n background-color: #fff;\\n border: 1px solid #aaa;\\n content: '';\\n float: right;\\n margin-right: -1em;\\n margin-top: -1px;\\n height: 0.9em;\\n width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 7\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 8\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 9\n// module chunks = 0","/////////////////////////////////////\r\n// Marching cubes lookup tables\r\n/////////////////////////////////////\r\n\r\n// Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/\r\n// These tables are straight from Paul Bourke's page:\r\n// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/\r\n// who in turn got them from Cory Gene Bloyd.\r\n\r\nvar EDGE_TABLE = new Int32Array([\r\n 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,\r\n 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,\r\n 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,\r\n 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,\r\n 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,\r\n 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,\r\n 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,\r\n 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,\r\n 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c,\r\n 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,\r\n 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc,\r\n 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,\r\n 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c,\r\n 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,\r\n 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,\r\n 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,\r\n 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,\r\n 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,\r\n 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,\r\n 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,\r\n 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,\r\n 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,\r\n 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,\r\n 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460,\r\n 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,\r\n 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0,\r\n 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,\r\n 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230,\r\n 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,\r\n 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,\r\n 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,\r\n 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0\r\n])\r\n\r\nvar TRI_TABLE = new Int32Array([\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,\r\n 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,\r\n 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1,\r\n 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1,\r\n 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1,\r\n 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1,\r\n 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1,\r\n 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1,\r\n 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1,\r\n 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1,\r\n 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1,\r\n 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,\r\n 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,\r\n 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,\r\n 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,\r\n 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,\r\n 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,\r\n 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,\r\n 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,\r\n 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,\r\n 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,\r\n 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,\r\n 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,\r\n 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,\r\n 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,\r\n 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,\r\n 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,\r\n 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,\r\n 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,\r\n 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,\r\n 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,\r\n 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,\r\n 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,\r\n 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,\r\n 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1,\r\n 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1,\r\n 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1,\r\n 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1,\r\n 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1,\r\n 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1,\r\n 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1,\r\n 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1,\r\n 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1,\r\n 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1,\r\n 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1,\r\n 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1,\r\n 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1,\r\n 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1,\r\n 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1,\r\n 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1,\r\n 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1,\r\n 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1,\r\n 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1,\r\n 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1,\r\n 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1,\r\n 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1,\r\n 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1,\r\n 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1,\r\n 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1,\r\n 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1,\r\n 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1,\r\n 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1,\r\n 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1,\r\n 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1,\r\n 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1,\r\n 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1,\r\n 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1,\r\n 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1,\r\n 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1,\r\n 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1,\r\n 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1,\r\n 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1,\r\n 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1,\r\n 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1,\r\n 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1,\r\n 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1,\r\n 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1,\r\n 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1,\r\n 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1,\r\n 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1,\r\n 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1,\r\n 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1,\r\n 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1,\r\n 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1,\r\n 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1,\r\n 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1,\r\n 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1,\r\n 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1,\r\n 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1,\r\n 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1,\r\n 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1,\r\n 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1,\r\n 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 3, 8, -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, -1, -1\r\n]);\r\n\r\nexport default {\r\n EDGE_TABLE: EDGE_TABLE,\r\n TRI_TABLE: TRI_TABLE\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cube_LUT.js","const THREE = require('three');\r\nimport {silverTexture} from './textures'\r\n\r\nimport Metaball from './metaball.js';\r\nimport InspectPoint from './inspect_point.js'\r\nimport LUT from './marching_cube_LUT.js';\r\nvar VISUAL_DEBUG = true;\r\nvar episolon = 0.1;\r\nvar balls = [];\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null};\r\n\r\n// lava\r\nvar l_mat = {\r\n uniforms: {\r\n texture: {type: \"t\",value: null},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/lava-vert.glsl'),\r\n fragmentShader: require('./shaders/lava-frag.glsl')\r\n};\r\n\r\nconst LAVA_MAT = new THREE.ShaderMaterial(l_mat);\r\nconst LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 });\r\nconst LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 });\r\nconst WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );\r\n\r\n// This function samples a point from the metaball's density function\r\n// Implement a function that returns the value of the all metaballs influence to a given point.\r\n// Please follow the resources given in the write-up for details.\r\nfunction sample(point) {\r\n var isovalue = 0.0;\r\n for (var i = 0; i < balls.length; i ++) {\r\n var r = balls[i].radius;\r\n var d = point.distanceTo(balls[i].pos);\r\n //isovalue += (r * r / (d * d)) * balls[i].neg;\r\n isovalue += (r * r / (d * d));\r\n }\r\n return isovalue;\r\n}\r\n\r\nexport default class MarchingCubes {\r\n\r\n constructor(App) {\r\n this.init(App);\r\n }\r\n\r\n init(App) {\r\n this.isPaused = false;\r\n VISUAL_DEBUG = App.config.visualDebug;\r\n\r\n // Initializing member variables.\r\n // Additional variables are used for fast computation.\r\n this.origin = new THREE.Vector3(0);\r\n\r\n this.isolevel = App.config.isolevel;\r\n this.minRadius = App.config.minRadius;\r\n this.maxRadius = App.config.maxRadius;\r\n\r\n this.gridCellWidth = App.config.gridCellWidth;\r\n this.gridCellHeight = App.config.gridCellHeight;\r\n this.gridCellDepth = App.config.gridCellDepth;\r\n this.halfCellWidth = App.config.gridCellWidth / 2.0;\r\n this.halfCellHeight = App.config.gridCellHeight / 2.0;\r\n this.halfCellDepth = App.config.gridCellDepth / 2.0;\r\n this.gridWidth = App.config.gridWidth;\r\n this.gridHeight = App.config.gridHeight;\r\n this.gridDepth = App.config.gridDepth;\r\n\r\n this.res = App.config.gridRes;\r\n this.res2 = App.config.gridRes * App.config.gridRes;\r\n this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes;\r\n\r\n this.maxSpeedX = App.config.maxSpeedX;\r\n this.maxSpeedY = App.config.maxSpeedY;\r\n this.maxSpeedZ = App.config.maxSpeedZ;\r\n this.numMetaballs = App.config.numMetaballs;\r\n\r\n this.camera = App.camera;\r\n this.scene = App.scene;\r\n\r\n this.voxels = [];\r\n //this.labels = [];\r\n this.balls = balls;\r\n\r\n this.showSpheres = true;\r\n this.showGrid = true;\r\n\r\n silverTexture.then(function(texture) {\r\n l_mat.uniforms.texture.value = texture;\r\n });\r\n\r\n if (App.config.material) {\r\n this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d});\r\n } else {\r\n this.material = App.config.material;\r\n }\r\n\r\n this.setupCells();\r\n this.setupMetaballs();\r\n this.makeMesh();\r\n };\r\n\r\n // Convert from 1D index to 3D indices\r\n i1toi3(i1) {\r\n\r\n // [i % w, i % (h * w)) / w, i / (h * w)]\r\n\r\n // @note: ~~ is a fast substitute for Math.floor()\r\n return [\r\n i1 % this.res,\r\n ~~ ((i1 % this.res2) / this.res),\r\n ~~ (i1 / this.res2)\r\n ];\r\n };\r\n\r\n // Convert from 3D indices to 1 1D\r\n i3toi1(i3x, i3y, i3z) {\r\n\r\n // [x + y * w + z * w * h]\r\n\r\n return i3x + i3y * this.res + i3z * this.res2;\r\n };\r\n\r\n // Convert from 3D indices to 3D positions\r\n i3toPos(i3) {\r\n\r\n return new THREE.Vector3(\r\n i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth,\r\n i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight,\r\n i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth\r\n );\r\n };\r\n\r\n setupCells() {\r\n\r\n // Allocate voxels based on our grid resolution\r\n this.voxels = [];\r\n for (var i = 0; i < this.res3; i++) {\r\n var i3 = this.i1toi3(i);\r\n var {x, y, z} = this.i3toPos(i3);\r\n var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth);\r\n this.voxels.push(voxel);\r\n\r\n if (VISUAL_DEBUG) {\r\n this.scene.add(voxel.wireframe);\r\n this.scene.add(voxel.mesh);\r\n }\r\n }\r\n }\r\n\r\n setupMetaballs() {\r\n\r\n var x, y, z, vx, vy, vz, radius, pos, vel;\r\n var matLambertWhite = LAMBERT_WHITE;\r\n var maxRadiusTRippled = this.maxRadius * 3;\r\n var maxRadiusDoubled = this.maxRadius * 2;\r\n\r\n // Randomly generate metaballs with different sizes and velocities\r\n for (var i = 0; i < this.numMetaballs; i++) {\r\n x = this.gridWidth / 2;\r\n y = this.gridHeight / 2;\r\n z = this.gridDepth / 2;\r\n pos = new THREE.Vector3(3, 3, 3);\r\n\r\n vx = 0\r\n vy = (Math.random() * 2 - 1) * this.maxSpeedY;\r\n vz = 0\r\n vel = new THREE.Vector3(vx, vy, vz);\r\n\r\n radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius;\r\n var neg = 1;\r\n if (Math.random()>0.75) neg = -1;\r\n var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG);\r\n balls.push(ball);\r\n\r\n // if (VISUAL_DEBUG) {\r\n // this.scene.add(ball.mesh);\r\n // }\r\n }\r\n this.balls = balls;\r\n }\r\n\r\n update() {\r\n\r\n if (this.isPaused) {\r\n return;\r\n }\r\n\r\n // This should move the metaballs\r\n balls.forEach(function(ball) {\r\n ball.update();\r\n });\r\n this.balls = balls;\r\n\r\n for (var c = 0; c < this.res3; c++) { // every voxel\r\n\r\n // Sampling the center and vertex points\r\n this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos);\r\n for (var i = 0; i < 8; i ++) {\r\n this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos);\r\n }\r\n\r\n // Visualizing grid\r\n if (VISUAL_DEBUG && this.showGrid) {\r\n\r\n // Toggle voxels on or off\r\n if (this.voxels[c].center.isovalue > this.isolevel) {\r\n this.voxels[c].show();\r\n } else {\r\n this.voxels[c].hide();\r\n }\r\n this.voxels[c].center.updateLabel(this.camera);\r\n } else {\r\n this.voxels[c].center.clearLabel();\r\n }\r\n }\r\n\r\n this.updateMesh();\r\n }\r\n\r\n pause() {\r\n this.isPaused = true;\r\n }\r\n\r\n play() {\r\n this.isPaused = false;\r\n }\r\n\r\n show() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].show();\r\n }\r\n this.showGrid = true;\r\n };\r\n\r\n hide() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].hide();\r\n }\r\n this.showGrid = false;\r\n };\r\n\r\n makeMesh() {\r\n // @TODO\r\n var geo = new THREE.Geometry();\r\n this.mesh = new THREE.Mesh(geo, LAVA_MAT);\r\n this.mesh.geometry.dynamic = true;\r\n this.scene.add(this.mesh);\r\n }\r\n\r\n updateMesh() {\r\n // @TODO\r\n var vertices = [];\r\n var faces = [];\r\n var count = 0;\r\n for (var i = 0; i < this.res3; i ++) {\r\n var vox_count = 0;\r\n var vANDn = this.voxels[i].polygonize(this.isolevel);\r\n for (var j = 0; j < vANDn.vertPositions.length/3; j ++) {\r\n var normals = [];\r\n for (var k = 0; k < 3; k ++) {\r\n vertices.push(vANDn.vertPositions[vox_count]);\r\n normals.push(vANDn.vertNormals[vox_count]);\r\n vox_count++;\r\n count++;\r\n }\r\n faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals));\r\n }\r\n }\r\n this.mesh.geometry.vertices = vertices;\r\n //this.mesh.geometry.normals = normals;\r\n this.mesh.geometry.faces = faces;\r\n this.mesh.geometry.verticesNeedUpdate = true;\r\n this.mesh.geometry.normalsNeedUpdate = true;\r\n this.mesh.geometry.elementsNeedUpdate = true;\r\n this.mesh.geometry.computeFaceNormals();\r\n //console.log(this.mesh);\r\n }\r\n};\r\n\r\n// ------------------------------------------- //\r\n\r\nclass Voxel {\r\n\r\n constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.init(position, gridCellWidth, gridCellHeight, gridCellDepth);\r\n }\r\n\r\n init(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.pos = position;\r\n this.gridCellWidth = gridCellWidth;\r\n this.gridCellHeight = gridCellHeight;\r\n this.gridCellDepth = gridCellDepth;\r\n this.corners = [];\r\n\r\n if (VISUAL_DEBUG) {\r\n this.makeMesh();\r\n }\r\n\r\n this.makeInspectPoints();\r\n }\r\n\r\n makeMesh() {\r\n var halfGridCellWidth = this.gridCellWidth / 2.0;\r\n var halfGridCellHeight = this.gridCellHeight / 2.0;\r\n var halfGridCellDepth = this.gridCellDepth / 2.0;\r\n\r\n var positions = new Float32Array([\r\n // Front face\r\n halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n\r\n // Back face\r\n -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n ]);\r\n\r\n var indices = new Uint16Array([\r\n 0, 1, 2, 3,\r\n 4, 5, 6, 7,\r\n 0, 7, 7, 4,\r\n 4, 3, 3, 0,\r\n 1, 6, 6, 5,\r\n 5, 2, 2, 1\r\n ]);\r\n\r\n // Buffer geometry\r\n var geo = new THREE.BufferGeometry();\r\n geo.setIndex( new THREE.BufferAttribute( indices, 1 ) );\r\n geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\r\n\r\n // Wireframe line segments\r\n this.wireframe = new THREE.LineSegments( geo, WIREFRAME_MAT );\r\n this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n\r\n // Green cube\r\n geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth);\r\n this.mesh = new THREE.Mesh( geo, LAMBERT_GREEN );\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n\r\n makeInspectPoints() {\r\n var w = this.gridCellWidth / 2.0;\r\n var h = this.gridCellHeight / 2.0;\r\n var d = this.gridCellDepth / 2.0;\r\n var x = this.pos.x;\r\n var y = this.pos.y;\r\n var z = this.pos.z;\r\n var red = 0xff0000;\r\n\r\n // Center dot\r\n this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG);\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG));\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n if (this.wireframe) {\r\n this.wireframe.visible = true;\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n\r\n if (this.wireframe) {\r\n this.wireframe.visible = false;\r\n }\r\n\r\n if (this.center) {\r\n this.center.clearLabel();\r\n }\r\n }\r\n\r\n vertexLerp(isolevel, posA, posB) {\r\n var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue);\r\n var lerpPos = new THREE.Vector3();\r\n return lerpPos.lerpVectors(posA.pos, posB.pos, t);\r\n }\r\n\r\n // returns an array of points on the cube edges\r\n // null if no point exists for an edge\r\n edgePoints(edges, x) {\r\n var points = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]);\r\n if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]);\r\n if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]);\r\n if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]);\r\n if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]);\r\n if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]);\r\n if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]);\r\n if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]);\r\n if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]);\r\n if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]);\r\n if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]);\r\n if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]);\r\n return points;\r\n }\r\n\r\n getNormal(point) {\r\n var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z);\r\n var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z);\r\n var x = sample(x1) - sample(x0);\r\n var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z);\r\n var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z);\r\n var y = sample(y1) - sample(y0);\r\n var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon);\r\n var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon);\r\n var z = sample(z1) - sample(z0);\r\n var n = new THREE.Vector3(x,y,z);\r\n return n.normalize();\r\n }\r\n\r\n polygonize(isolevel) {\r\n\r\n var vertexList = [];\r\n var normalList = [];\r\n var faceList = [];\r\n\r\n // get corner vertices that are inside metaballs\r\n var corner = 1;\r\n var allVert = 0;\r\n for (var i = 0; i < 8; i ++) {\r\n if (this.corners[i].isovalue > isolevel) {\r\n allVert |= corner;\r\n }\r\n corner = corner << 1;\r\n }\r\n\r\n if (allVert != 0) {\r\n // get intersected edges\r\n var edges = LUT.EDGE_TABLE[allVert];\r\n\r\n // get 12 points\r\n var points = this.edgePoints(edges, isolevel);\r\n\r\n for (var j = 0; j < 16; j ++) {\r\n var tri = LUT.TRI_TABLE[allVert*16 + j];\r\n if (tri < 0) break;\r\n var vertex = points[tri];\r\n vertexList.push(vertex);\r\n normalList.push(this.getNormal(vertex));\r\n }\r\n }\r\n\r\n\r\n return {\r\n vertPositions: vertexList,\r\n vertNormals: normalList\r\n };\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cubes.js","const THREE = require('three')\r\n\r\nvar SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32);\r\nvar LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 });\r\n\r\nexport default class Metaball {\r\n constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug);\r\n }\r\n\r\n init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.gridWidth = gridWidth;\r\n this.gridHeight = gridHeight;\r\n this.gridDepth = gridDepth;\r\n this.pos = pos;\r\n this.vel = vel;\r\n this.neg = neg;\r\n this.radius = radius;\r\n this.radius2 = radius * radius;\r\n this.mesh = null;\r\n this.debug = visualDebug;\r\n // if (visualDebug) {\r\n // this.makeMesh();\r\n // }\r\n }\r\n\r\n makeMesh() {\r\n this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE);\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n this.mesh.scale.set(this.radius, this.radius, this.radius);\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n };\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n };\r\n\r\n update() {\r\n\r\n // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z);\r\n // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir);\r\n // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2));\r\n // if ((dist + 2*this.radius) > this.gridWidth \r\n // || (dist + 2*this.radius) > this.gridDepth) {\r\n // this.vel.add(disp);\r\n // }\r\n var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0;\r\n if (y) this.vel.y *= -1;\r\n \r\n var date = new Date();\r\n var velocity = new THREE.Vector3();\r\n velocity.copy(this.vel).multiplyScalar(3);\r\n this.pos.add(velocity);\r\n\r\n \r\n\r\n \r\n // if (x || y || z) {\r\n // this.vel.multiplyScalar(-1);\r\n // }\r\n if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/metaball.js","const THREE = require('three');\r\n\r\nconst POINT_MATERIAL = new THREE.PointsMaterial( { color: 0xee1111, size: 10, sizeAttenuation: true } );\r\n\r\nexport default class InspectPoint {\r\n\r\n constructor(pos, isovalue, visualDebug) {\r\n this.init(pos, isovalue, visualDebug);\r\n }\r\n\r\n init(pos, isovalue, visualDebug) {\r\n this.pos = pos;\r\n this.isovalue = isovalue;\r\n this.label = null;\r\n\r\n if (visualDebug) {\r\n this.makeLabel();\r\n }\r\n };\r\n\r\n // Create an HTML div for holding label\r\n makeLabel() {\r\n this.label = document.createElement('div');\r\n this.label.style.position = 'absolute';\r\n this.label.style.width = 100;\r\n this.label.style.height = 100;\r\n this.label.style.userSelect = 'none';\r\n this.label.style.cursor = 'default';\r\n this.label.style.fontSize = '0.3em';\r\n this.label.style.pointerEvents = 'none';\r\n document.body.appendChild(this.label); \r\n };\r\n\r\n updateLabel(camera) {\r\n if (this.label) {\r\n var screenPos = this.pos.clone().project(camera);\r\n screenPos.x = ( screenPos.x + 1 ) / 2 * window.innerWidth;;\r\n screenPos.y = - ( screenPos.y - 1 ) / 2 * window.innerHeight;;\r\n\r\n this.label.style.top = screenPos.y + 'px';\r\n this.label.style.left = screenPos.x + 'px';\r\n this.label.innerHTML = this.isovalue.toFixed(2);\r\n this.label.style.opacity = this.isovalue - 0.5; \r\n }\r\n };\r\n\r\n clearLabel() {\r\n if (this.label) {\r\n this.label.innerHTML = '';\r\n this.label.style.opacity = 0;\r\n }\r\n };\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/inspect_point.js","module.exports = \"\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normalMatrix * normal;\\r\\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\nuniform sampler2D texture;\\r\\nuniform vec3 u_ambient;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 ref = reflect(e_position, f_normal);\\r\\n\\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\\r\\n float x = f_normal.x/m + 0.5;\\r\\n float y = f_normal.y/m + 0.5;\\r\\n\\r\\n vec4 color = texture2D(texture, vec2(x,y));\\r\\n\\r\\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","'use strict';\n\nmodule.exports = function (THREE) {\n\n /**\n * @author mrdoob / http://mrdoob.com/\n */\n THREE.OBJLoader = function (manager) {\n\n this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;\n };\n\n THREE.OBJLoader.prototype = {\n\n constructor: THREE.OBJLoader,\n\n load: function load(url, onLoad, onProgress, onError) {\n\n var scope = this;\n\n var loader = new THREE.XHRLoader(scope.manager);\n loader.load(url, function (text) {\n\n onLoad(scope.parse(text));\n }, onProgress, onError);\n },\n\n parse: function parse(text) {\n\n console.time('OBJLoader');\n\n var object,\n objects = [];\n var geometry, material;\n\n function parseVertexIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3;\n }\n\n function parseNormalIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + normals.length / 3) * 3;\n }\n\n function parseUVIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2;\n }\n\n function addVertex(a, b, c) {\n\n geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]);\n }\n\n function addNormal(a, b, c) {\n\n geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]);\n }\n\n function addUV(a, b, c) {\n\n geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]);\n }\n\n function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\n var ia = parseVertexIndex(a);\n var ib = parseVertexIndex(b);\n var ic = parseVertexIndex(c);\n var id;\n\n if (d === undefined) {\n\n addVertex(ia, ib, ic);\n } else {\n\n id = parseVertexIndex(d);\n\n addVertex(ia, ib, id);\n addVertex(ib, ic, id);\n }\n\n if (ua !== undefined) {\n\n ia = parseUVIndex(ua);\n ib = parseUVIndex(ub);\n ic = parseUVIndex(uc);\n\n if (d === undefined) {\n\n addUV(ia, ib, ic);\n } else {\n\n id = parseUVIndex(ud);\n\n addUV(ia, ib, id);\n addUV(ib, ic, id);\n }\n }\n\n if (na !== undefined) {\n\n ia = parseNormalIndex(na);\n ib = parseNormalIndex(nb);\n ic = parseNormalIndex(nc);\n\n if (d === undefined) {\n\n addNormal(ia, ib, ic);\n } else {\n\n id = parseNormalIndex(nd);\n\n addNormal(ia, ib, id);\n addNormal(ib, ic, id);\n }\n }\n }\n\n // create mesh if no objects in text\n\n if (/^o /gm.test(text) === false) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: '',\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n }\n\n var vertices = [];\n var normals = [];\n var uvs = [];\n\n // v float float float\n\n var vertex_pattern = /v( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vn float float float\n\n var normal_pattern = /vn( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vt float float\n\n var uv_pattern = /vt( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // f vertex vertex vertex ...\n\n var face_pattern1 = /f( +-?\\d+)( +-?\\d+)( +-?\\d+)( +-?\\d+)?/;\n\n // f vertex/uv vertex/uv vertex/uv ...\n\n var face_pattern2 = /f( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...\n\n var face_pattern3 = /f( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex//normal vertex//normal vertex//normal ...\n\n var face_pattern4 = /f( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))?/;\n\n //\n\n var lines = text.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n\n var line = lines[i];\n line = line.trim();\n\n var result;\n\n if (line.length === 0 || line.charAt(0) === '#') {\n\n continue;\n } else if ((result = vertex_pattern.exec(line)) !== null) {\n\n // [\"v 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = normal_pattern.exec(line)) !== null) {\n\n // [\"vn 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = uv_pattern.exec(line)) !== null) {\n\n // [\"vt 0.1 0.2\", \"0.1\", \"0.2\"]\n\n uvs.push(parseFloat(result[1]), parseFloat(result[2]));\n } else if ((result = face_pattern1.exec(line)) !== null) {\n\n // [\"f 1 2 3\", \"1\", \"2\", \"3\", undefined]\n\n addFace(result[1], result[2], result[3], result[4]);\n } else if ((result = face_pattern2.exec(line)) !== null) {\n\n // [\"f 1/1 2/2 3/3\", \" 1/1\", \"1\", \"1\", \" 2/2\", \"2\", \"2\", \" 3/3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]);\n } else if ((result = face_pattern3.exec(line)) !== null) {\n\n // [\"f 1/1/1 2/2/2 3/3/3\", \" 1/1/1\", \"1\", \"1\", \"1\", \" 2/2/2\", \"2\", \"2\", \"2\", \" 3/3/3\", \"3\", \"3\", \"3\", undefined, undefined, undefined, undefined]\n\n addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]);\n } else if ((result = face_pattern4.exec(line)) !== null) {\n\n // [\"f 1//1 2//2 3//3\", \" 1//1\", \"1\", \"1\", \" 2//2\", \"2\", \"2\", \" 3//3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]);\n } else if (/^o /.test(line)) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: line.substring(2).trim(),\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n } else if (/^g /.test(line)) {\n\n // group\n\n } else if (/^usemtl /.test(line)) {\n\n // material\n\n material.name = line.substring(7).trim();\n } else if (/^mtllib /.test(line)) {\n\n // mtl file\n\n } else if (/^s /.test(line)) {\n\n // smooth shading\n\n } else {\n\n // console.log( \"THREE.OBJLoader: Unhandled line \" + line );\n\n }\n }\n\n var container = new THREE.Object3D();\n var l;\n\n for (i = 0, l = objects.length; i < l; i++) {\n\n object = objects[i];\n geometry = object.geometry;\n\n var buffergeometry = new THREE.BufferGeometry();\n\n buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3));\n\n if (geometry.normals.length > 0) {\n\n buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3));\n }\n\n if (geometry.uvs.length > 0) {\n\n buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2));\n }\n\n material = new THREE.MeshLambertMaterial({\n color: 0xff0000\n });\n material.name = object.material.name;\n\n var mesh = new THREE.Mesh(buffergeometry, material);\n mesh.name = object.name;\n\n container.add(mesh);\n }\n\n console.timeEnd('OBJLoader');\n\n return container;\n }\n\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-obj-loader/dist/index.js\n// module id = 17\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n e_position = cameraPosition;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-vert.glsl\n// module id = 18\n// module chunks = 0","module.exports = \"#define M_PI 3.1415926535897932384626433832795\\r\\n\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nfloat cosine(float a, float b, float c, float d, float t) {\\r\\n\\treturn a + b * cos(2.0 * M_PI * (c * t + d));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\\r\\n\\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\\r\\n\\r\\n gl_FragColor = vec4(d,d,d, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-frag.glsl\n// module id = 19\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-vert.glsl\n// module id = 20\n// module chunks = 0","module.exports = \"uniform vec3 u_lightPos;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\\r\\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\\r\\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-frag.glsl\n// module id = 21\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/build/index.html b/build/index.html new file mode 100644 index 0000000..e68ca85 --- /dev/null +++ b/build/index.html @@ -0,0 +1,42 @@ + + + + Lava Lamp + + + +
+
+

+

+
+
+ + + + diff --git a/glass.mtl b/glass.mtl new file mode 100644 index 0000000..c89145d --- /dev/null +++ b/glass.mtl @@ -0,0 +1,6 @@ +newmtl initialShadingGroup +illum 4 +Kd 0.50 0.50 0.50 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +Ni 1.00 diff --git a/glass.obj b/glass.obj new file mode 100644 index 0000000..11a96f9 --- /dev/null +++ b/glass.obj @@ -0,0 +1,4423 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib glass.mtl +g default +v 1.034828 0.023645 5.000000 +v 2.478410 15.929955 5.000000 +v 7.521590 15.929955 5.000000 +v 8.965172 0.023645 5.000000 +v 1.417236 7.928881 5.000000 +v 8.582764 7.928881 5.000000 +v 3.208639 7.928881 1.897309 +v 3.017437 0.023645 1.566141 +v 0.875664 2.621381 5.000000 +v 2.937856 2.621381 1.428304 +v 1.428295 2.621381 2.937872 +v 1.566132 0.023645 3.017453 +v 0.821208 0.615620 5.000000 +v 1.381136 0.615620 2.910645 +v 0.963631 0.615620 3.918452 +v 1.169970 0.023645 3.973740 +v 0.894509 0.142910 5.000000 +v 1.034433 0.142910 3.937423 +v 0.929731 0.142910 4.464145 +v 1.068846 0.023645 4.482460 +v 0.956291 0.039097 5.000000 +v 0.990983 0.039097 4.472209 +v 0.964993 0.039097 4.735543 +v 1.043362 0.023645 4.740679 +v 0.993465 0.020326 5.000000 +v 1.002088 0.020326 4.737974 +v 1.027838 0.020326 4.477061 +v 1.094110 0.039097 3.953414 +v 1.111107 0.023645 4.226447 +v 1.034081 0.039097 4.211125 +v 1.070540 0.020326 4.218377 +v 1.130017 0.020326 3.963035 +v 1.444614 0.142910 2.947294 +v 1.336707 0.023645 3.482630 +v 1.207070 0.142910 3.428933 +v 1.264149 0.039097 3.452576 +v 1.245260 0.023645 3.725444 +v 1.170891 0.039097 3.700200 +v 1.206092 0.020326 3.712149 +v 1.298493 0.020326 3.466802 +v 1.498118 0.039097 2.978185 +v 1.443833 0.023645 3.246301 +v 1.373397 0.039097 3.211566 +v 1.406737 0.020326 3.228007 +v 1.530311 0.020326 2.996772 +v 2.910628 0.615620 1.381145 +v 2.196266 0.023645 2.196279 +v 2.045218 0.615620 2.045232 +v 2.097048 0.142910 2.097061 +v 1.854217 0.023645 2.586172 +v 1.742894 0.142910 2.500752 +v 1.791910 0.039097 2.538362 +v 1.703097 0.023645 2.797079 +v 1.637796 0.039097 2.753446 +v 1.668705 0.020326 2.774099 +v 1.821402 0.020326 2.560992 +v 2.140734 0.039097 2.140747 +v 2.018867 0.023645 2.385640 +v 1.959821 0.039097 2.333858 +v 1.987769 0.020326 2.358368 +v 2.167019 0.020326 2.167032 +v 2.947278 0.142910 1.444624 +v 2.586158 0.023645 1.854228 +v 2.500737 0.142910 1.742906 +v 2.538347 0.039097 1.791921 +v 2.385627 0.023645 2.018879 +v 2.333844 0.039097 1.959833 +v 2.358355 0.020326 1.987781 +v 2.560978 0.020326 1.821413 +v 2.978169 0.039097 1.498128 +v 2.797064 0.023645 1.703107 +v 2.753431 0.039097 1.637806 +v 2.774084 0.020326 1.668715 +v 2.996756 0.020326 1.530321 +v 1.117453 5.293516 5.000000 +v 3.058749 5.293516 1.637695 +v 1.637686 5.293516 3.058764 +v 0.974417 3.840676 5.000000 +v 1.513815 3.840676 2.987248 +v 2.987231 3.840676 1.513825 +v 1.897300 7.928881 3.208653 +v 1.254732 6.544681 5.000000 +v 1.756570 6.544681 3.127403 +v 3.127388 6.544681 1.756579 +v 9.124336 2.621381 5.000000 +v 6.982563 0.023645 1.566141 +v 7.062144 2.621381 1.428304 +v 5.000000 0.023645 1.034828 +v 5.000000 2.621381 0.875664 +v 5.000000 0.615620 0.821208 +v 3.973732 0.023645 1.169972 +v 3.918442 0.615620 0.963634 +v 3.937414 0.142910 1.034436 +v 3.482617 0.023645 1.336712 +v 3.428920 0.142910 1.207076 +v 3.452563 0.039097 1.264154 +v 3.246287 0.023645 1.443840 +v 3.211552 0.039097 1.373404 +v 3.227993 0.020326 1.406744 +v 3.466789 0.020326 1.298498 +v 3.953405 0.039097 1.094112 +v 3.725433 0.023645 1.245263 +v 3.700189 0.039097 1.170894 +v 3.712138 0.020326 1.206095 +v 3.963026 0.020326 1.130019 +v 5.000000 0.142910 0.894509 +v 4.482456 0.023645 1.068847 +v 4.464141 0.142910 0.929731 +v 4.472205 0.039097 0.990984 +v 4.226440 0.023645 1.111109 +v 4.211118 0.039097 1.034083 +v 4.218370 0.020326 1.070542 +v 4.477057 0.020326 1.027839 +v 5.000000 0.039097 0.956291 +v 4.740677 0.023645 1.043362 +v 4.735540 0.039097 0.964994 +v 4.737971 0.020326 1.002088 +v 5.000000 0.020326 0.993465 +v 7.089372 0.615620 1.381145 +v 6.026268 0.023645 1.169972 +v 6.081558 0.615620 0.963634 +v 6.062586 0.142910 1.034436 +v 5.517544 0.023645 1.068847 +v 5.535859 0.142910 0.929731 +v 5.527795 0.039097 0.990984 +v 5.259323 0.023645 1.043362 +v 5.264460 0.039097 0.964994 +v 5.262029 0.020326 1.002088 +v 5.522943 0.020326 1.027839 +v 6.046595 0.039097 1.094112 +v 5.773560 0.023645 1.111109 +v 5.788882 0.039097 1.034083 +v 5.781630 0.020326 1.070542 +v 6.036974 0.020326 1.130019 +v 7.052722 0.142910 1.444624 +v 6.517383 0.023645 1.336712 +v 6.571080 0.142910 1.207076 +v 6.547437 0.039097 1.264154 +v 6.274567 0.023645 1.245263 +v 6.299811 0.039097 1.170894 +v 6.287862 0.020326 1.206095 +v 6.533211 0.020326 1.298498 +v 7.021831 0.039097 1.498128 +v 6.753713 0.023645 1.443840 +v 6.788448 0.039097 1.373404 +v 6.772007 0.020326 1.406744 +v 7.003244 0.020326 1.530321 +v 8.433868 0.023645 3.017453 +v 8.571705 2.621381 2.937872 +v 8.618864 0.615620 2.910645 +v 7.803734 0.023645 2.196279 +v 7.954782 0.615620 2.045232 +v 7.902952 0.142910 2.097061 +v 7.413842 0.023645 1.854228 +v 7.499263 0.142910 1.742906 +v 7.461653 0.039097 1.791921 +v 7.202936 0.023645 1.703107 +v 7.246569 0.039097 1.637806 +v 7.225916 0.020326 1.668715 +v 7.439022 0.020326 1.821413 +v 7.859266 0.039097 2.140747 +v 7.614373 0.023645 2.018879 +v 7.666156 0.039097 1.959833 +v 7.641645 0.020326 1.987781 +v 7.832981 0.020326 2.167032 +v 8.555386 0.142910 2.947294 +v 8.145783 0.023645 2.586172 +v 8.257106 0.142910 2.500752 +v 8.208090 0.039097 2.538362 +v 7.981133 0.023645 2.385640 +v 8.040179 0.039097 2.333858 +v 8.012231 0.020326 2.358368 +v 8.178598 0.020326 2.560992 +v 8.501882 0.039097 2.978185 +v 8.296903 0.023645 2.797079 +v 8.362204 0.039097 2.753446 +v 8.331295 0.020326 2.774099 +v 8.469689 0.020326 2.996772 +v 9.178792 0.615620 5.000000 +v 8.830030 0.023645 3.973740 +v 9.036369 0.615620 3.918452 +v 8.965567 0.142910 3.937423 +v 8.663293 0.023645 3.482630 +v 8.792930 0.142910 3.428933 +v 8.735851 0.039097 3.452576 +v 8.556167 0.023645 3.246301 +v 8.626603 0.039097 3.211566 +v 8.593263 0.020326 3.228007 +v 8.701507 0.020326 3.466802 +v 8.905890 0.039097 3.953414 +v 8.754740 0.023645 3.725444 +v 8.829109 0.039097 3.700200 +v 8.793908 0.020326 3.712149 +v 8.869983 0.020326 3.963035 +v 9.105491 0.142910 5.000000 +v 8.931154 0.023645 4.482460 +v 9.070269 0.142910 4.464145 +v 9.009017 0.039097 4.472209 +v 8.888893 0.023645 4.226447 +v 8.965919 0.039097 4.211125 +v 8.929460 0.020326 4.218377 +v 8.972162 0.020326 4.477061 +v 9.043709 0.039097 5.000000 +v 8.956638 0.023645 4.740679 +v 9.035007 0.039097 4.735543 +v 8.997912 0.020326 4.737974 +v 9.006535 0.020326 5.000000 +v 6.791361 7.928881 1.897309 +v 6.941251 5.293516 1.637695 +v 5.000000 5.293516 1.117453 +v 5.000000 3.840676 0.974417 +v 7.012769 3.840676 1.513825 +v 5.000000 7.928881 1.417236 +v 5.000000 6.544681 1.254732 +v 6.872612 6.544681 1.756579 +v 8.882547 5.293516 5.000000 +v 8.362314 5.293516 3.058764 +v 8.486185 3.840676 2.987248 +v 9.025583 3.840676 5.000000 +v 8.102700 7.928881 3.208653 +v 8.243430 6.544681 3.127403 +v 8.745268 6.544681 5.000000 +v 3.739220 15.929955 2.816291 +v 1.753123 10.600694 5.000000 +v 3.376580 10.600694 2.188188 +v 2.188181 10.600694 3.376593 +v 1.575982 9.216277 5.000000 +v 2.034775 9.216277 3.288024 +v 3.288010 9.216277 2.034783 +v 2.109344 13.271226 5.000000 +v 3.554689 13.271226 2.496678 +v 2.496671 13.271226 3.554700 +v 1.924119 11.898438 5.000000 +v 2.336265 11.898438 3.462090 +v 3.462077 11.898438 2.336272 +v 2.816285 15.929955 3.739230 +v 2.288120 14.570229 5.000000 +v 2.651492 14.570229 3.644087 +v 3.644076 14.570229 2.651499 +v 8.246877 10.600694 5.000000 +v 6.623420 10.600694 2.188188 +v 5.000000 10.600694 1.753123 +v 5.000000 9.216277 1.575982 +v 6.711990 9.216277 2.034783 +v 7.811819 10.600694 3.376593 +v 7.965225 9.216277 3.288024 +v 8.424018 9.216277 5.000000 +v 6.260780 15.929955 2.816291 +v 6.445311 13.271226 2.496678 +v 5.000000 13.271226 2.109344 +v 5.000000 11.898438 1.924119 +v 6.537923 11.898438 2.336272 +v 5.000000 15.929955 2.478410 +v 5.000000 14.570229 2.288120 +v 6.355924 14.570229 2.651499 +v 7.890656 13.271226 5.000000 +v 7.503329 13.271226 3.554700 +v 7.663735 11.898438 3.462090 +v 8.075881 11.898438 5.000000 +v 7.183715 15.929955 3.739230 +v 7.348508 14.570229 3.644087 +v 7.711880 14.570229 5.000000 +v 6.982563 0.023645 8.433859 +v 6.791361 7.928881 8.102691 +v 7.062144 2.621381 8.571696 +v 8.433868 0.023645 6.982547 +v 8.571705 2.621381 7.062128 +v 8.618864 0.615620 7.089355 +v 8.830030 0.023645 6.026260 +v 9.036369 0.615620 6.081548 +v 8.965567 0.142910 6.062577 +v 8.931154 0.023645 5.517540 +v 9.070269 0.142910 5.535855 +v 9.009017 0.039097 5.527791 +v 8.956638 0.023645 5.259321 +v 9.035007 0.039097 5.264457 +v 8.997912 0.020326 5.262026 +v 8.972162 0.020326 5.522939 +v 8.905890 0.039097 6.046586 +v 8.888893 0.023645 5.773553 +v 8.965919 0.039097 5.788875 +v 8.929460 0.020326 5.781623 +v 8.869983 0.020326 6.036965 +v 8.555386 0.142910 7.052706 +v 8.663293 0.023645 6.517370 +v 8.792930 0.142910 6.571067 +v 8.735851 0.039097 6.547424 +v 8.754740 0.023645 6.274556 +v 8.829109 0.039097 6.299800 +v 8.793908 0.020326 6.287851 +v 8.701507 0.020326 6.533198 +v 8.501882 0.039097 7.021815 +v 8.556167 0.023645 6.753699 +v 8.626603 0.039097 6.788434 +v 8.593263 0.020326 6.771993 +v 8.469689 0.020326 7.003228 +v 7.089372 0.615620 8.618855 +v 7.803734 0.023645 7.803721 +v 7.954782 0.615620 7.954768 +v 7.902952 0.142910 7.902939 +v 8.145783 0.023645 7.413828 +v 8.257106 0.142910 7.499248 +v 8.208090 0.039097 7.461638 +v 8.296903 0.023645 7.202921 +v 8.362204 0.039097 7.246554 +v 8.331295 0.020326 7.225901 +v 8.178598 0.020326 7.439008 +v 7.859266 0.039097 7.859253 +v 7.981133 0.023645 7.614360 +v 8.040179 0.039097 7.666142 +v 8.012231 0.020326 7.641632 +v 7.832981 0.020326 7.832968 +v 7.052722 0.142910 8.555376 +v 7.413842 0.023645 8.145772 +v 7.499263 0.142910 8.257094 +v 7.461653 0.039097 8.208079 +v 7.614373 0.023645 7.981121 +v 7.666156 0.039097 8.040167 +v 7.641645 0.020326 8.012219 +v 7.439022 0.020326 8.178587 +v 7.021831 0.039097 8.501872 +v 7.202936 0.023645 8.296893 +v 7.246569 0.039097 8.362194 +v 7.225916 0.020326 8.331285 +v 7.003244 0.020326 8.469679 +v 6.941251 5.293516 8.362305 +v 8.362314 5.293516 6.941236 +v 8.486185 3.840676 7.012752 +v 7.012769 3.840676 8.486175 +v 8.102700 7.928881 6.791347 +v 8.243430 6.544681 6.872597 +v 6.872612 6.544681 8.243421 +v 3.017437 0.023645 8.433859 +v 2.937856 2.621381 8.571696 +v 5.000000 0.023645 8.965172 +v 5.000000 2.621381 9.124336 +v 5.000000 0.615620 9.178792 +v 6.026268 0.023645 8.830028 +v 6.081558 0.615620 9.036366 +v 6.062586 0.142910 8.965564 +v 6.517383 0.023645 8.663288 +v 6.571080 0.142910 8.792924 +v 6.547437 0.039097 8.735846 +v 6.753713 0.023645 8.556160 +v 6.788448 0.039097 8.626596 +v 6.772007 0.020326 8.593256 +v 6.533211 0.020326 8.701502 +v 6.046595 0.039097 8.905888 +v 6.274567 0.023645 8.754737 +v 6.299811 0.039097 8.829106 +v 6.287862 0.020326 8.793905 +v 6.036974 0.020326 8.869981 +v 5.000000 0.142910 9.105491 +v 5.517544 0.023645 8.931153 +v 5.535859 0.142910 9.070269 +v 5.527795 0.039097 9.009016 +v 5.773560 0.023645 8.888891 +v 5.788882 0.039097 8.965917 +v 5.781630 0.020326 8.929458 +v 5.522943 0.020326 8.972161 +v 5.000000 0.039097 9.043709 +v 5.259323 0.023645 8.956638 +v 5.264460 0.039097 9.035006 +v 5.262029 0.020326 8.997912 +v 5.000000 0.020326 9.006535 +v 2.910628 0.615620 8.618855 +v 3.973732 0.023645 8.830028 +v 3.918442 0.615620 9.036366 +v 3.937414 0.142910 8.965564 +v 4.482456 0.023645 8.931153 +v 4.464141 0.142910 9.070269 +v 4.472205 0.039097 9.009016 +v 4.740677 0.023645 8.956638 +v 4.735540 0.039097 9.035006 +v 4.737971 0.020326 8.997912 +v 4.477057 0.020326 8.972161 +v 3.953405 0.039097 8.905888 +v 4.226440 0.023645 8.888891 +v 4.211118 0.039097 8.965917 +v 4.218370 0.020326 8.929458 +v 3.963026 0.020326 8.869981 +v 2.947278 0.142910 8.555376 +v 3.482617 0.023645 8.663288 +v 3.428920 0.142910 8.792924 +v 3.452563 0.039097 8.735846 +v 3.725433 0.023645 8.754737 +v 3.700189 0.039097 8.829106 +v 3.712138 0.020326 8.793905 +v 3.466789 0.020326 8.701502 +v 2.978169 0.039097 8.501872 +v 3.246287 0.023645 8.556160 +v 3.211552 0.039097 8.626596 +v 3.227993 0.020326 8.593256 +v 2.996756 0.020326 8.469679 +v 1.566132 0.023645 6.982547 +v 1.428295 2.621381 7.062128 +v 1.381136 0.615620 7.089355 +v 2.196266 0.023645 7.803721 +v 2.045218 0.615620 7.954768 +v 2.097048 0.142910 7.902939 +v 2.586158 0.023645 8.145772 +v 2.500737 0.142910 8.257094 +v 2.538347 0.039097 8.208079 +v 2.797064 0.023645 8.296893 +v 2.753431 0.039097 8.362194 +v 2.774084 0.020326 8.331285 +v 2.560978 0.020326 8.178587 +v 2.140734 0.039097 7.859253 +v 2.385627 0.023645 7.981121 +v 2.333844 0.039097 8.040167 +v 2.358355 0.020326 8.012219 +v 2.167019 0.020326 7.832968 +v 1.444614 0.142910 7.052706 +v 1.854217 0.023645 7.413828 +v 1.742894 0.142910 7.499248 +v 1.791910 0.039097 7.461638 +v 2.018867 0.023645 7.614360 +v 1.959821 0.039097 7.666142 +v 1.987769 0.020326 7.641632 +v 1.821402 0.020326 7.439008 +v 1.498118 0.039097 7.021815 +v 1.703097 0.023645 7.202921 +v 1.637796 0.039097 7.246554 +v 1.668705 0.020326 7.225901 +v 1.530311 0.020326 7.003228 +v 1.169970 0.023645 6.026260 +v 0.963631 0.615620 6.081548 +v 1.034433 0.142910 6.062577 +v 1.336707 0.023645 6.517370 +v 1.207070 0.142910 6.571067 +v 1.264149 0.039097 6.547424 +v 1.443833 0.023645 6.753699 +v 1.373397 0.039097 6.788434 +v 1.406737 0.020326 6.771993 +v 1.298493 0.020326 6.533198 +v 1.094110 0.039097 6.046586 +v 1.245260 0.023645 6.274556 +v 1.170891 0.039097 6.299800 +v 1.206092 0.020326 6.287851 +v 1.130017 0.020326 6.036965 +v 3.208639 7.928881 8.102691 +v 3.058749 5.293516 8.362305 +v 5.000000 5.293516 8.882547 +v 5.000000 3.840676 9.025583 +v 2.987231 3.840676 8.486175 +v 5.000000 7.928881 8.582764 +v 5.000000 6.544681 8.745268 +v 3.127388 6.544681 8.243421 +v 1.637686 5.293516 6.941236 +v 1.513815 3.840676 7.012752 +v 1.897300 7.928881 6.791347 +v 1.756570 6.544681 6.872597 +v 6.260780 15.929955 7.183709 +v 6.623420 10.600694 7.811812 +v 7.811819 10.600694 6.623407 +v 7.965225 9.216277 6.711976 +v 6.711990 9.216277 7.965217 +v 6.445311 13.271226 7.503322 +v 7.503329 13.271226 6.445300 +v 7.663735 11.898438 6.537910 +v 6.537923 11.898438 7.663728 +v 7.183715 15.929955 6.260770 +v 7.348508 14.570229 6.355913 +v 6.355924 14.570229 7.348501 +v 3.376580 10.600694 7.811812 +v 5.000000 10.600694 8.246877 +v 5.000000 9.216277 8.424018 +v 3.288010 9.216277 7.965217 +v 2.188181 10.600694 6.623407 +v 2.034775 9.216277 6.711976 +v 3.739220 15.929955 7.183709 +v 3.554689 13.271226 7.503322 +v 5.000000 13.271226 7.890656 +v 5.000000 11.898438 8.075881 +v 3.462077 11.898438 7.663728 +v 5.000000 15.929955 7.521590 +v 5.000000 14.570229 7.711880 +v 3.644076 14.570229 7.348501 +v 2.496671 13.271226 6.445300 +v 2.336265 11.898438 6.537910 +v 2.816285 15.929955 6.260770 +v 2.651492 14.570229 6.355913 +vt 1.000000 0.916667 +vt 1.000000 1.000000 +vt 0.957053 0.916667 +vt 1.000000 0.416667 +vt 1.000000 0.500000 +vt 0.957053 0.416667 +vt 0.710046 0.416667 +vt 0.710046 0.500000 +vt 0.646478 0.416667 +vt 0.710046 0.083333 +vt 0.710046 0.166666 +vt 0.646478 0.083333 +vt 0.414458 0.083333 +vt 0.414458 0.166666 +vt 0.207229 0.166666 +vt 0.207229 0.000000 +vt 0.414458 0.000000 +vt 0.207229 0.083333 +vt 0.103615 0.083333 +vt 0.103615 0.062500 +vt 0.207229 0.041667 +vt 0.103615 0.041667 +vt 0.103615 0.020833 +vt 0.051807 0.041667 +vt 0.051807 0.031250 +vt 0.051807 0.020833 +vt 0.051807 0.010417 +vt 0.025904 0.010417 +vt 0.025904 0.000000 +vt 0.051807 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.010417 +vt 0.025904 0.020833 +vt 0.025904 0.031250 +vt 0.000000 0.020833 +vt 0.000000 0.031250 +vt 0.025904 0.041667 +vt 0.051807 0.083333 +vt 0.051807 0.072916 +vt 0.051807 0.062500 +vt 0.051807 0.052083 +vt 0.025904 0.052083 +vt 0.000000 0.041667 +vt 0.000000 0.052083 +vt 0.025904 0.062500 +vt 0.025904 0.072916 +vt 0.000000 0.062500 +vt 0.000000 0.072916 +vt 0.025904 0.083333 +vt 0.103615 0.145833 +vt 0.103615 0.125000 +vt 0.207229 0.125000 +vt 0.103615 0.104166 +vt 0.051807 0.125000 +vt 0.051807 0.114583 +vt 0.051807 0.104166 +vt 0.051807 0.093750 +vt 0.025904 0.093750 +vt 0.000000 0.083333 +vt 0.000000 0.093750 +vt 0.025904 0.104166 +vt 0.025904 0.114583 +vt 0.000000 0.104166 +vt 0.000000 0.114583 +vt 0.025904 0.125000 +vt 0.103615 0.166666 +vt 0.051807 0.166666 +vt 0.051807 0.156250 +vt 0.051807 0.145833 +vt 0.051807 0.135416 +vt 0.025904 0.135416 +vt 0.000000 0.125000 +vt 0.000000 0.135416 +vt 0.025904 0.145833 +vt 0.025904 0.156250 +vt 0.000000 0.145833 +vt 0.000000 0.156250 +vt 0.025904 0.166666 +vt 0.582909 0.083333 +vt 0.582909 0.166666 +vt 0.498684 0.083333 +vt 0.498684 0.000000 +vt 0.582909 0.000000 +vt 0.498684 0.166666 +vt 0.646478 0.000000 +vt 0.710046 0.000000 +vt 0.646478 0.166666 +vt 0.207229 0.458333 +vt 0.207229 0.416667 +vt 0.414458 0.416667 +vt 0.207229 0.250000 +vt 0.414458 0.250000 +vt 0.414458 0.333334 +vt 0.103615 0.250000 +vt 0.103615 0.229167 +vt 0.207229 0.208333 +vt 0.103615 0.208333 +vt 0.103615 0.187500 +vt 0.051807 0.208333 +vt 0.051807 0.197916 +vt 0.051807 0.187500 +vt 0.051807 0.177083 +vt 0.025904 0.177083 +vt 0.000000 0.166666 +vt 0.000000 0.177083 +vt 0.025904 0.187500 +vt 0.025904 0.197916 +vt 0.000000 0.187500 +vt 0.000000 0.197916 +vt 0.025904 0.208333 +vt 0.051807 0.250000 +vt 0.051807 0.239583 +vt 0.051807 0.229167 +vt 0.051807 0.218750 +vt 0.025904 0.218750 +vt 0.000000 0.208333 +vt 0.000000 0.218750 +vt 0.025904 0.229167 +vt 0.025904 0.239583 +vt 0.000000 0.229167 +vt 0.000000 0.239583 +vt 0.025904 0.250000 +vt 0.207229 0.333334 +vt 0.103615 0.333334 +vt 0.103615 0.312500 +vt 0.207229 0.291667 +vt 0.103615 0.291667 +vt 0.103615 0.270833 +vt 0.051807 0.291667 +vt 0.051807 0.281250 +vt 0.051807 0.270833 +vt 0.051807 0.260417 +vt 0.025904 0.260417 +vt 0.000000 0.250000 +vt 0.000000 0.260417 +vt 0.025904 0.270833 +vt 0.025904 0.281250 +vt 0.000000 0.270833 +vt 0.000000 0.281250 +vt 0.025904 0.291667 +vt 0.051807 0.333334 +vt 0.051807 0.322917 +vt 0.051807 0.312500 +vt 0.051807 0.302084 +vt 0.025904 0.302084 +vt 0.000000 0.291667 +vt 0.000000 0.302084 +vt 0.025904 0.312500 +vt 0.025904 0.322917 +vt 0.000000 0.312500 +vt 0.000000 0.322917 +vt 0.025904 0.333334 +vt 0.103615 0.416667 +vt 0.103615 0.395834 +vt 0.207229 0.375000 +vt 0.103615 0.375000 +vt 0.103615 0.354167 +vt 0.051807 0.375000 +vt 0.051807 0.364584 +vt 0.051807 0.354167 +vt 0.051807 0.343750 +vt 0.025904 0.343750 +vt 0.000000 0.333334 +vt 0.000000 0.343750 +vt 0.025904 0.354167 +vt 0.025904 0.364584 +vt 0.000000 0.354167 +vt 0.000000 0.364584 +vt 0.025904 0.375000 +vt 0.051807 0.416667 +vt 0.051807 0.406250 +vt 0.051807 0.395834 +vt 0.051807 0.385417 +vt 0.025904 0.385417 +vt 0.000000 0.375000 +vt 0.000000 0.385417 +vt 0.025904 0.395834 +vt 0.025904 0.406250 +vt 0.000000 0.395834 +vt 0.000000 0.406250 +vt 0.025904 0.416667 +vt 0.103615 0.479167 +vt 0.103615 0.458333 +vt 0.103615 0.437500 +vt 0.051807 0.458333 +vt 0.051807 0.447917 +vt 0.051807 0.437500 +vt 0.051807 0.427084 +vt 0.025904 0.427084 +vt 0.000000 0.416667 +vt 0.000000 0.427084 +vt 0.025904 0.437500 +vt 0.025904 0.447917 +vt 0.000000 0.437500 +vt 0.000000 0.447917 +vt 0.025904 0.458333 +vt 0.051807 0.489583 +vt 0.051807 0.479167 +vt 0.051807 0.468750 +vt 0.025904 0.468750 +vt 0.000000 0.458333 +vt 0.000000 0.468750 +vt 0.025904 0.479167 +vt 0.025904 0.489583 +vt 0.051807 0.500000 +vt 0.000000 0.479167 +vt 0.000000 0.489583 +vt 0.025904 0.500000 +vt 0.710046 0.250000 +vt 0.710046 0.333334 +vt 0.646478 0.250000 +vt 0.498684 0.250000 +vt 0.582909 0.250000 +vt 0.582909 0.333334 +vt 0.498684 0.333334 +vt 0.646478 0.333334 +vt 0.498684 0.416667 +vt 0.582909 0.416667 +vt 0.582909 0.500000 +vt 0.498684 0.500000 +vt 0.646478 0.500000 +vt 1.000000 0.083333 +vt 1.000000 0.166666 +vt 0.957053 0.083333 +vt 0.818618 0.083333 +vt 0.818618 0.166666 +vt 0.764332 0.083333 +vt 0.764332 0.000000 +vt 0.818618 0.000000 +vt 0.764332 0.166666 +vt 0.914105 0.083333 +vt 0.914105 0.166666 +vt 0.866362 0.083333 +vt 0.866362 0.000000 +vt 0.914105 0.000000 +vt 0.866362 0.166666 +vt 0.957053 0.000000 +vt 1.000000 0.000000 +vt 0.957053 0.166666 +vt 0.764332 0.416667 +vt 0.818618 0.416667 +vt 0.818618 0.500000 +vt 0.764332 0.250000 +vt 0.818618 0.250000 +vt 0.818618 0.333334 +vt 0.764332 0.333334 +vt 0.764332 0.500000 +vt 1.000000 0.250000 +vt 1.000000 0.333334 +vt 0.957053 0.250000 +vt 0.866362 0.250000 +vt 0.914105 0.250000 +vt 0.914105 0.333334 +vt 0.866362 0.333334 +vt 0.957053 0.333334 +vt 0.866362 0.416667 +vt 0.914105 0.416667 +vt 0.914105 0.500000 +vt 0.866362 0.500000 +vt 0.957053 0.500000 +vt 0.646478 0.916667 +vt 0.710046 0.916667 +vt 0.710046 1.000000 +vt 0.710046 0.583333 +vt 0.710046 0.666666 +vt 0.646478 0.583333 +vt 0.414458 0.583333 +vt 0.414458 0.666666 +vt 0.207229 0.666666 +vt 0.207229 0.500000 +vt 0.414458 0.500000 +vt 0.207229 0.583333 +vt 0.103615 0.583333 +vt 0.103615 0.562500 +vt 0.207229 0.541667 +vt 0.103615 0.541667 +vt 0.103615 0.520833 +vt 0.051807 0.541667 +vt 0.051807 0.531250 +vt 0.051807 0.520833 +vt 0.051807 0.510417 +vt 0.025904 0.510417 +vt 0.000000 0.500000 +vt 0.000000 0.510417 +vt 0.025904 0.520833 +vt 0.025904 0.531250 +vt 0.000000 0.520833 +vt 0.000000 0.531250 +vt 0.025904 0.541667 +vt 0.051807 0.583333 +vt 0.051807 0.572916 +vt 0.051807 0.562500 +vt 0.051807 0.552083 +vt 0.025904 0.552083 +vt 0.000000 0.541667 +vt 0.000000 0.552083 +vt 0.025904 0.562500 +vt 0.025904 0.572916 +vt 0.000000 0.562500 +vt 0.000000 0.572916 +vt 0.025904 0.583333 +vt 0.103615 0.666666 +vt 0.103615 0.645833 +vt 0.207229 0.625000 +vt 0.103615 0.625000 +vt 0.103615 0.604166 +vt 0.051807 0.625000 +vt 0.051807 0.614583 +vt 0.051807 0.604166 +vt 0.051807 0.593750 +vt 0.025904 0.593750 +vt 0.000000 0.583333 +vt 0.000000 0.593750 +vt 0.025904 0.604166 +vt 0.025904 0.614583 +vt 0.000000 0.604166 +vt 0.000000 0.614583 +vt 0.025904 0.625000 +vt 0.051807 0.666666 +vt 0.051807 0.656250 +vt 0.051807 0.645833 +vt 0.051807 0.635416 +vt 0.025904 0.635416 +vt 0.000000 0.625000 +vt 0.000000 0.635416 +vt 0.025904 0.645833 +vt 0.025904 0.656250 +vt 0.000000 0.645833 +vt 0.000000 0.656250 +vt 0.025904 0.666666 +vt 0.582909 0.583333 +vt 0.582909 0.666666 +vt 0.498684 0.583333 +vt 0.498684 0.666666 +vt 0.646478 0.666666 +vt 0.207229 0.958333 +vt 0.207229 0.916667 +vt 0.414458 0.916667 +vt 0.207229 0.750000 +vt 0.414458 0.750000 +vt 0.414458 0.833334 +vt 0.103615 0.750000 +vt 0.103615 0.729167 +vt 0.207229 0.708333 +vt 0.103615 0.708333 +vt 0.103615 0.687500 +vt 0.051807 0.708333 +vt 0.051807 0.697916 +vt 0.051807 0.687500 +vt 0.051807 0.677083 +vt 0.025904 0.677083 +vt 0.000000 0.666666 +vt 0.000000 0.677083 +vt 0.025904 0.687500 +vt 0.025904 0.697916 +vt 0.000000 0.687500 +vt 0.000000 0.697916 +vt 0.025904 0.708333 +vt 0.051807 0.750000 +vt 0.051807 0.739583 +vt 0.051807 0.729167 +vt 0.051807 0.718750 +vt 0.025904 0.718750 +vt 0.000000 0.708333 +vt 0.000000 0.718750 +vt 0.025904 0.729167 +vt 0.025904 0.739583 +vt 0.000000 0.729167 +vt 0.000000 0.739583 +vt 0.025904 0.750000 +vt 0.207229 0.833334 +vt 0.103615 0.833334 +vt 0.103615 0.812500 +vt 0.207229 0.791667 +vt 0.103615 0.791667 +vt 0.103615 0.770833 +vt 0.051807 0.791667 +vt 0.051807 0.781250 +vt 0.051807 0.770833 +vt 0.051807 0.760417 +vt 0.025904 0.760417 +vt 0.000000 0.750000 +vt 0.000000 0.760417 +vt 0.025904 0.770833 +vt 0.025904 0.781250 +vt 0.000000 0.770833 +vt 0.000000 0.781250 +vt 0.025904 0.791667 +vt 0.051807 0.833334 +vt 0.051807 0.822917 +vt 0.051807 0.812500 +vt 0.051807 0.802084 +vt 0.025904 0.802084 +vt 0.000000 0.791667 +vt 0.000000 0.802084 +vt 0.025904 0.812500 +vt 0.025904 0.822917 +vt 0.000000 0.812500 +vt 0.000000 0.822917 +vt 0.025904 0.833334 +vt 0.103615 0.916667 +vt 0.103615 0.895834 +vt 0.207229 0.875000 +vt 0.103615 0.875000 +vt 0.103615 0.854167 +vt 0.051807 0.875000 +vt 0.051807 0.864584 +vt 0.051807 0.854167 +vt 0.051807 0.843750 +vt 0.025904 0.843750 +vt 0.000000 0.833334 +vt 0.000000 0.843750 +vt 0.025904 0.854167 +vt 0.025904 0.864584 +vt 0.000000 0.854167 +vt 0.000000 0.864584 +vt 0.025904 0.875000 +vt 0.051807 0.916667 +vt 0.051807 0.906250 +vt 0.051807 0.895834 +vt 0.051807 0.885417 +vt 0.025904 0.885417 +vt 0.000000 0.875000 +vt 0.000000 0.885417 +vt 0.025904 0.895834 +vt 0.025904 0.906250 +vt 0.000000 0.895834 +vt 0.000000 0.906250 +vt 0.025904 0.916667 +vt 0.103615 0.958333 +vt 0.207229 1.000000 +vt 0.103615 0.937500 +vt 0.051807 0.958333 +vt 0.051807 0.947917 +vt 0.051807 0.937500 +vt 0.051807 0.927084 +vt 0.025904 0.927084 +vt 0.000000 0.916667 +vt 0.000000 0.927084 +vt 0.025904 0.937500 +vt 0.025904 0.947917 +vt 0.000000 0.937500 +vt 0.000000 0.947917 +vt 0.025904 0.958333 +vt 0.000000 1.000000 +vt 0.000000 0.958333 +vt 0.710046 0.750000 +vt 0.710046 0.833334 +vt 0.646478 0.750000 +vt 0.498684 0.750000 +vt 0.582909 0.750000 +vt 0.582909 0.833334 +vt 0.498684 0.833334 +vt 0.646478 0.833334 +vt 0.498684 0.916667 +vt 0.582909 0.916667 +vt 0.582909 1.000000 +vt 0.498684 1.000000 +vt 0.646478 1.000000 +vt 1.000000 0.583333 +vt 1.000000 0.666666 +vt 0.957053 0.583333 +vt 0.764332 0.583333 +vt 0.818618 0.583333 +vt 0.818618 0.666666 +vt 0.764332 0.666666 +vt 0.866362 0.583333 +vt 0.914105 0.583333 +vt 0.914105 0.666666 +vt 0.866362 0.666666 +vt 0.957053 0.666666 +vt 0.764332 0.916667 +vt 0.818618 0.916667 +vt 0.818618 1.000000 +vt 0.764332 0.750000 +vt 0.818618 0.750000 +vt 0.818618 0.833334 +vt 0.764332 0.833334 +vt 0.764332 1.000000 +vt 1.000000 0.750000 +vt 1.000000 0.833334 +vt 0.957053 0.750000 +vt 0.866362 0.750000 +vt 0.914105 0.750000 +vt 0.914105 0.833334 +vt 0.866362 0.833334 +vt 0.957053 0.833334 +vt 0.866362 0.916667 +vt 0.914105 0.916667 +vt 0.914105 1.000000 +vt 0.866362 1.000000 +vt 0.957053 1.000000 +vt 0.103615 0.000000 +vt 0.103615 0.500000 +vt 0.414458 1.000000 +vt 0.103615 1.000000 +vt 0.051807 1.000000 +vt 0.025904 1.000000 +vn -0.855158 0.138592 0.499497 +vn -0.990337 0.138595 0.004983 +vn -0.855477 0.137445 0.499267 +vn 0.855158 0.138592 -0.499497 +vn 0.990337 0.138595 -0.004983 +vn 0.855477 0.137445 -0.499267 +vn 0.858038 0.119287 -0.499541 +vn 0.992853 0.119290 -0.003582 +vn 0.858835 0.112906 -0.499655 +vn -0.861619 0.119288 -0.493338 +vn -0.499543 0.119288 -0.858037 +vn -0.862116 0.112906 -0.493972 +vn -0.864783 0.062737 -0.498211 +vn -0.522059 0.054243 -0.851183 +vn -0.559013 0.035015 -0.828420 +vn -0.998818 0.048476 0.003588 +vn -0.998889 0.047128 0.000794 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.848748 -0.198912 -0.489960 +vn -0.915190 -0.136671 -0.379143 +vn -0.970776 0.085464 -0.224254 +vn -0.946638 -0.198907 -0.253600 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.753817 -0.625309 -0.201863 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.773684 -0.625316 -0.101943 +vn -0.834536 -0.548214 -0.054865 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.774567 -0.626221 0.088845 +vn -0.834536 -0.548214 -0.054865 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.199250 -0.979861 -0.013125 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.753817 -0.625309 -0.201863 +vn -0.197953 -0.979864 -0.026106 +vn -0.773684 -0.625316 -0.101943 +vn -0.820199 -0.548350 -0.163050 +vn 0.079314 -0.996795 0.010461 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn -0.195829 -0.979864 -0.038953 +vn -0.192889 -0.979859 -0.051676 +vn -0.848748 -0.198912 -0.489960 +vn -0.675878 -0.625313 -0.390093 +vn -0.749973 -0.548375 -0.369898 +vn -0.915190 -0.136671 -0.379143 +vn -0.720908 -0.625314 -0.298787 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.192889 -0.979859 -0.051676 +vn -0.753817 -0.625309 -0.201863 +vn -0.792045 -0.548040 -0.268918 +vn 0.077272 -0.996795 0.020703 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn -0.189096 -0.979856 -0.064228 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.675878 -0.625313 -0.390093 +vn -0.184454 -0.979861 -0.076474 +vn -0.720908 -0.625314 -0.298787 +vn -0.749973 -0.548375 -0.369898 +vn 0.073898 -0.996795 0.030640 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn -0.179057 -0.979865 -0.088341 +vn -0.172924 -0.979863 -0.099831 +vn -0.603081 -0.136554 -0.785905 +vn -0.692977 -0.198918 -0.692975 +vn -0.679581 0.085468 -0.728605 +vn -0.679581 0.085468 -0.728605 +vn -0.692977 -0.198918 -0.692975 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.551796 -0.625317 -0.551816 +vn -0.628648 -0.548296 -0.551520 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.619062 -0.625306 -0.475137 +vn -0.172924 -0.979863 -0.099831 +vn -0.675878 -0.625313 -0.390093 +vn -0.695502 -0.548117 -0.464591 +vn 0.069281 -0.996795 0.039999 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn -0.166042 -0.979858 -0.110944 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.551796 -0.625317 -0.551816 +vn -0.158405 -0.979857 -0.121607 +vn -0.619062 -0.625306 -0.475137 +vn -0.628648 -0.548296 -0.551520 +vn 0.063454 -0.996795 0.048715 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn -0.150082 -0.979862 -0.131702 +vn -0.141165 -0.979865 -0.141202 +vn -0.489963 -0.198913 -0.848746 +vn -0.390067 -0.625315 -0.675892 +vn -0.464580 -0.548113 -0.695513 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.475115 -0.625305 -0.619080 +vn -0.141165 -0.979865 -0.141202 +vn -0.551796 -0.625317 -0.551816 +vn -0.551508 -0.548294 -0.628659 +vn 0.056560 -0.996795 0.056577 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn -0.131662 -0.979863 -0.150115 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.390067 -0.625315 -0.675892 +vn -0.121566 -0.979857 -0.158438 +vn -0.475115 -0.625305 -0.619080 +vn -0.464580 -0.548113 -0.695513 +vn 0.048696 -0.996795 0.063468 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn -0.110900 -0.979858 -0.166071 +vn -0.099785 -0.979863 -0.172949 +vn -0.862907 0.102956 -0.494765 +vn -0.499945 0.102956 -0.859916 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.994681 0.102958 0.002990 +vn -0.862907 0.102956 -0.494765 +vn -0.998889 0.047128 0.000794 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.863780 0.089908 -0.495782 +vn -0.500192 0.089907 -0.861234 +vn -0.993600 0.112908 0.003282 +vn -0.992853 0.119290 0.003582 +vn -0.861619 0.119288 -0.493338 +vn -0.994681 0.102958 0.002990 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.862116 0.112906 -0.493972 +vn -0.499657 0.112906 -0.858834 +vn 0.970776 0.085464 -0.224254 +vn 0.865986 0.007573 -0.500011 +vn 0.863839 0.062737 -0.499846 +vn -0.000000 0.054620 -0.998507 +vn -0.000794 0.047128 -0.998889 +vn 0.520588 0.054246 -0.852083 +vn -0.522059 0.054243 -0.851183 +vn -0.000794 0.047128 -0.998889 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.000000 -0.198908 -0.980018 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.253603 -0.198906 -0.946637 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.201834 -0.625309 -0.753825 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.298761 -0.625313 -0.720920 +vn -0.099785 -0.979863 -0.172949 +vn -0.390067 -0.625315 -0.675892 +vn -0.369884 -0.548374 -0.749982 +vn 0.039978 -0.996795 0.069293 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn -0.088294 -0.979865 -0.179080 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.201834 -0.625309 -0.753825 +vn -0.076426 -0.979861 -0.184474 +vn -0.298761 -0.625313 -0.720920 +vn -0.268901 -0.548039 -0.792052 +vn 0.030617 -0.996795 0.073907 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn -0.064178 -0.979856 -0.189113 +vn -0.051625 -0.979859 -0.192902 +vn 0.000000 -0.198908 -0.980018 +vn 0.000016 -0.625302 -0.780383 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn -0.101911 -0.625316 -0.773688 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.051625 -0.979859 -0.192902 +vn -0.201834 -0.625309 -0.753825 +vn -0.163032 -0.548348 -0.820204 +vn 0.020680 -0.996795 0.077279 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn -0.038902 -0.979864 -0.195841 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn 0.000016 -0.625302 -0.780383 +vn -0.026053 -0.979864 -0.197959 +vn -0.101911 -0.625316 -0.773688 +vn -0.054845 -0.548214 -0.834538 +vn 0.010437 -0.996795 0.079315 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn -0.013072 -0.979860 -0.199255 +vn 0.000027 -0.979855 -0.199708 +vn 0.559013 0.035015 -0.828420 +vn 0.489963 -0.198913 -0.848746 +vn 0.379146 -0.136670 -0.915188 +vn 0.224256 0.085466 -0.970775 +vn 0.253603 -0.198906 -0.946637 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.201864 -0.625309 -0.753817 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.101942 -0.625316 -0.773684 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.000027 -0.979855 -0.199708 +vn 0.000016 -0.625302 -0.780383 +vn 0.054866 -0.548214 -0.834537 +vn -0.000012 -0.996795 0.079997 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn 0.013125 -0.979860 -0.199252 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.201864 -0.625309 -0.753817 +vn 0.026105 -0.979864 -0.197952 +vn 0.101942 -0.625316 -0.773684 +vn 0.163052 -0.548348 -0.820200 +vn -0.010461 -0.996795 0.079312 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn 0.038954 -0.979864 -0.195830 +vn 0.051676 -0.979859 -0.192887 +vn 0.489963 -0.198913 -0.848746 +vn 0.390094 -0.625314 -0.675876 +vn 0.369902 -0.548374 -0.749972 +vn 0.379146 -0.136670 -0.915188 +vn 0.298790 -0.625312 -0.720908 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.051676 -0.979859 -0.192887 +vn 0.201864 -0.625309 -0.753817 +vn 0.268920 -0.548039 -0.792045 +vn -0.020704 -0.996795 0.077272 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn 0.064229 -0.979856 -0.189096 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.390094 -0.625314 -0.675876 +vn 0.076475 -0.979861 -0.184454 +vn 0.298790 -0.625312 -0.720908 +vn 0.369902 -0.548374 -0.749972 +vn -0.030640 -0.996795 0.073898 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn 0.088341 -0.979865 -0.179057 +vn 0.099830 -0.979863 -0.172922 +vn 0.559013 0.035015 -0.828420 +vn 0.520588 0.054246 -0.852083 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.848748 -0.198912 -0.489960 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.692977 -0.198918 -0.692975 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551819 -0.625315 -0.551794 +vn 0.551523 -0.548295 -0.628645 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.475140 -0.625305 -0.619061 +vn 0.099830 -0.979863 -0.172922 +vn 0.390094 -0.625314 -0.675876 +vn 0.464597 -0.548113 -0.695501 +vn -0.039999 -0.996795 0.069281 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn 0.110944 -0.979858 -0.166042 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.551819 -0.625315 -0.551794 +vn 0.121608 -0.979857 -0.158406 +vn 0.475140 -0.625305 -0.619061 +vn 0.551523 -0.548295 -0.628645 +vn -0.048715 -0.996795 0.063453 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn 0.131702 -0.979863 -0.150080 +vn 0.141203 -0.979865 -0.141164 +vn 0.848748 -0.198912 -0.489960 +vn 0.675893 -0.625315 -0.390065 +vn 0.695513 -0.548117 -0.464574 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.619082 -0.625304 -0.475112 +vn 0.141203 -0.979865 -0.141164 +vn 0.551819 -0.625315 -0.551794 +vn 0.628661 -0.548296 -0.551504 +vn -0.056577 -0.996795 0.056559 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn 0.150116 -0.979863 -0.131661 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.675893 -0.625315 -0.390065 +vn 0.158439 -0.979857 -0.121565 +vn 0.619082 -0.625304 -0.475112 +vn 0.695513 -0.548117 -0.464574 +vn -0.063469 -0.996795 0.048696 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn 0.166073 -0.979858 -0.110900 +vn 0.172949 -0.979863 -0.099784 +vn 0.982121 -0.136787 -0.129332 +vn 0.946638 -0.198907 -0.253600 +vn 0.970776 0.085464 -0.224254 +vn 0.970776 0.085464 -0.224254 +vn 0.946638 -0.198907 -0.253600 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.753824 -0.625311 -0.201832 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.720921 -0.625312 -0.298759 +vn 0.172949 -0.979863 -0.099784 +vn 0.675893 -0.625315 -0.390065 +vn 0.749983 -0.548375 -0.369880 +vn -0.069293 -0.996795 0.039977 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn 0.179081 -0.979865 -0.088293 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.753824 -0.625311 -0.201832 +vn 0.184475 -0.979861 -0.076425 +vn 0.720921 -0.625312 -0.298759 +vn 0.792052 -0.548040 -0.268898 +vn -0.073908 -0.996795 0.030617 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn 0.189113 -0.979856 -0.064178 +vn 0.192902 -0.979859 -0.051624 +vn 0.834538 -0.548214 -0.054844 +vn 0.773688 -0.625316 -0.101912 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.773688 -0.625316 -0.101912 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.192902 -0.979859 -0.051624 +vn 0.753824 -0.625311 -0.201832 +vn 0.820204 -0.548349 -0.163030 +vn -0.077279 -0.996795 0.020680 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn 0.195842 -0.979864 -0.038902 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.780383 -0.625302 0.000016 +vn 0.197959 -0.979864 -0.026053 +vn 0.773688 -0.625316 -0.101912 +vn 0.834538 -0.548214 -0.054844 +vn -0.079316 -0.996795 0.010437 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn 0.199256 -0.979860 -0.013072 +vn 0.199709 -0.979855 0.000026 +vn -0.003582 0.119290 -0.992853 +vn 0.493340 0.119288 -0.861618 +vn -0.003282 0.112908 -0.993600 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn 0.494767 0.102956 -0.862905 +vn -0.500192 0.089907 -0.861234 +vn -0.499945 0.102956 -0.859916 +vn -0.002990 0.102958 -0.994681 +vn -0.522059 0.054243 -0.851183 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.002546 0.089909 -0.995947 +vn 0.495785 0.089908 -0.863779 +vn -0.499543 0.119288 -0.858037 +vn -0.003582 0.119290 -0.992853 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.003282 0.112908 -0.993600 +vn 0.493974 0.112906 -0.862115 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.994681 0.102958 -0.002990 +vn 0.495785 0.089908 -0.863779 +vn 0.494767 0.102956 -0.862905 +vn 0.859917 0.102956 -0.499943 +vn 0.520588 0.054246 -0.852083 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.861235 0.089907 -0.500190 +vn 0.995947 0.089909 -0.002546 +vn 0.493340 0.119288 -0.861618 +vn 0.858038 0.119287 -0.499541 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.858835 0.112906 -0.499655 +vn 0.993600 0.112908 -0.003282 +vn -0.860140 0.138592 -0.490867 +vn -0.499499 0.138592 -0.855157 +vn -0.860102 0.137445 -0.491258 +vn -0.860841 0.128646 -0.492344 +vn -0.499366 0.128646 -0.856787 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.991682 0.128649 0.004054 +vn -0.860841 0.128646 -0.492344 +vn -0.992853 0.119290 0.003582 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.861162 0.124651 -0.492811 +vn -0.499410 0.124651 -0.857352 +vn -0.860318 0.134936 -0.491574 +vn -0.499299 0.134937 -0.855858 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.990844 0.134939 0.004460 +vn -0.860318 0.134936 -0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.860532 0.132157 -0.491955 +vn -0.499292 0.132157 -0.856295 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.860140 0.138592 -0.490867 +vn -0.990844 0.134939 0.004460 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.860102 0.137445 -0.491258 +vn -0.499269 0.137445 -0.855476 +vn 0.857353 0.124650 -0.499408 +vn 0.856788 0.128646 -0.499364 +vn 0.991682 0.128649 -0.004054 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn 0.492346 0.128646 -0.860840 +vn -0.499410 0.124651 -0.857352 +vn -0.499366 0.128646 -0.856787 +vn -0.004054 0.128649 -0.991682 +vn -0.499543 0.119288 -0.858037 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.003810 0.124653 -0.992193 +vn 0.492814 0.124651 -0.861160 +vn 0.492814 0.124651 -0.861160 +vn 0.492346 0.128646 -0.860840 +vn 0.856788 0.128646 -0.499364 +vn 0.493340 0.119288 -0.861618 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.857353 0.124650 -0.499408 +vn 0.992193 0.124653 -0.003810 +vn -0.004983 0.138595 -0.990337 +vn 0.490869 0.138592 -0.860139 +vn -0.004625 0.137448 -0.990498 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn 0.491576 0.134936 -0.860317 +vn -0.499292 0.132157 -0.856295 +vn -0.499299 0.134937 -0.855858 +vn -0.004460 0.134939 -0.990844 +vn -0.499366 0.128646 -0.856787 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.004236 0.132159 -0.991220 +vn 0.491957 0.132157 -0.860530 +vn -0.499499 0.138592 -0.855157 +vn -0.004983 0.138595 -0.990337 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.004625 0.137448 -0.990498 +vn 0.491260 0.137445 -0.860100 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.990844 0.134939 -0.004460 +vn 0.491957 0.132157 -0.860530 +vn 0.491576 0.134936 -0.860317 +vn 0.855859 0.134936 -0.499297 +vn 0.492346 0.128646 -0.860840 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.856296 0.132157 -0.499291 +vn 0.991220 0.132159 -0.004236 +vn 0.490869 0.138592 -0.860139 +vn 0.855158 0.138592 -0.499497 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.855477 0.137445 -0.499267 +vn 0.990498 0.137448 -0.004625 +vn -0.858835 0.112906 0.499655 +vn -0.858038 0.119288 0.499541 +vn -0.992853 0.119290 0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.499543 0.119288 0.858037 +vn 0.862116 0.112906 0.493972 +vn 0.864783 0.062737 0.498211 +vn 0.522059 0.054243 0.851183 +vn 0.559013 0.035015 0.828420 +vn 0.998507 0.054619 0.000000 +vn 0.998889 0.047128 -0.000794 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.848748 -0.198912 0.489960 +vn 0.915190 -0.136671 0.379143 +vn 0.970776 0.085464 0.224254 +vn 0.946638 -0.198907 0.253600 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.753817 -0.625309 0.201863 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.773684 -0.625316 0.101943 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.199709 -0.979855 0.000026 +vn 0.780383 -0.625302 0.000016 +vn 0.834536 -0.548215 0.054865 +vn -0.079997 -0.996795 -0.000012 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn 0.199250 -0.979861 0.013125 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.753817 -0.625309 0.201863 +vn 0.197953 -0.979864 0.026106 +vn 0.773684 -0.625316 0.101943 +vn 0.820199 -0.548350 0.163050 +vn -0.079314 -0.996795 -0.010461 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn 0.195829 -0.979864 0.038953 +vn 0.192889 -0.979859 0.051676 +vn 0.848748 -0.198912 0.489960 +vn 0.675878 -0.625313 0.390093 +vn 0.749973 -0.548375 0.369898 +vn 0.915190 -0.136671 0.379143 +vn 0.720908 -0.625314 0.298787 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.192889 -0.979859 0.051676 +vn 0.753817 -0.625309 0.201863 +vn 0.792045 -0.548040 0.268918 +vn -0.077272 -0.996795 -0.020703 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn 0.189096 -0.979856 0.064228 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.675878 -0.625313 0.390093 +vn 0.184454 -0.979861 0.076474 +vn 0.720908 -0.625314 0.298787 +vn 0.749973 -0.548375 0.369898 +vn -0.073898 -0.996795 -0.030640 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn 0.179057 -0.979865 0.088341 +vn 0.172924 -0.979863 0.099831 +vn 0.559013 0.035015 0.828420 +vn 0.489963 -0.198913 0.848746 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.692977 -0.198918 0.692975 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.551796 -0.625317 0.551816 +vn 0.628648 -0.548296 0.551520 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.619062 -0.625306 0.475137 +vn 0.172924 -0.979863 0.099831 +vn 0.675878 -0.625313 0.390093 +vn 0.695502 -0.548117 0.464591 +vn -0.069281 -0.996795 -0.039999 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn 0.166042 -0.979858 0.110944 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.551796 -0.625317 0.551816 +vn 0.158405 -0.979857 0.121607 +vn 0.619062 -0.625306 0.475137 +vn 0.628648 -0.548296 0.551520 +vn -0.063454 -0.996795 -0.048715 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn 0.150082 -0.979862 0.131702 +vn 0.141165 -0.979865 0.141202 +vn 0.489963 -0.198913 0.848746 +vn 0.390067 -0.625315 0.675892 +vn 0.464580 -0.548113 0.695513 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.475115 -0.625305 0.619080 +vn 0.141165 -0.979865 0.141202 +vn 0.551796 -0.625317 0.551816 +vn 0.551508 -0.548294 0.628659 +vn -0.056560 -0.996795 -0.056577 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn 0.131662 -0.979863 0.150115 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.390067 -0.625315 0.675892 +vn 0.121566 -0.979857 0.158438 +vn 0.475115 -0.625305 0.619080 +vn 0.464580 -0.548113 0.695513 +vn -0.048696 -0.996795 -0.063468 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn 0.110900 -0.979858 0.166071 +vn 0.099785 -0.979863 0.172949 +vn 0.862907 0.102956 0.494765 +vn 0.499945 0.102956 0.859916 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.994681 0.102958 -0.002990 +vn 0.862907 0.102956 0.494765 +vn 0.998889 0.047128 -0.000794 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.863780 0.089908 0.495782 +vn 0.500192 0.089907 0.861234 +vn 0.993600 0.112908 -0.003282 +vn 0.992853 0.119290 -0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.994681 0.102958 -0.002990 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.862116 0.112906 0.493972 +vn 0.499657 0.112906 0.858834 +vn -0.972486 0.075824 0.220276 +vn -0.865986 0.007573 0.500011 +vn -0.863839 0.062737 0.499846 +vn 0.000000 0.054620 0.998507 +vn 0.000794 0.047128 0.998889 +vn -0.520588 0.054246 0.852083 +vn 0.522059 0.054243 0.851183 +vn 0.000794 0.047128 0.998889 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn 0.000000 -0.198908 0.980018 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.253603 -0.198906 0.946637 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.201834 -0.625309 0.753825 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.298761 -0.625313 0.720920 +vn 0.099785 -0.979863 0.172949 +vn 0.390067 -0.625315 0.675892 +vn 0.369884 -0.548374 0.749982 +vn -0.039978 -0.996795 -0.069293 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn 0.088294 -0.979865 0.179080 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.201834 -0.625309 0.753825 +vn 0.076426 -0.979861 0.184474 +vn 0.298761 -0.625313 0.720920 +vn 0.268901 -0.548039 0.792052 +vn -0.030617 -0.996795 -0.073907 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn 0.064178 -0.979856 0.189113 +vn 0.051625 -0.979859 0.192902 +vn 0.000000 -0.198908 0.980018 +vn -0.000016 -0.625302 0.780383 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.101911 -0.625316 0.773688 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.051625 -0.979859 0.192902 +vn 0.201834 -0.625309 0.753825 +vn 0.163032 -0.548348 0.820204 +vn -0.020680 -0.996795 -0.077279 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn 0.038902 -0.979864 0.195841 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn -0.000016 -0.625302 0.780383 +vn 0.026053 -0.979864 0.197959 +vn 0.101911 -0.625316 0.773688 +vn 0.054845 -0.548214 0.834538 +vn -0.010437 -0.996795 -0.079315 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn 0.013072 -0.979860 0.199255 +vn -0.000027 -0.979855 0.199708 +vn -0.559013 0.035015 0.828420 +vn -0.489963 -0.198913 0.848746 +vn -0.379146 -0.136670 0.915188 +vn -0.224256 0.085466 0.970775 +vn -0.253603 -0.198906 0.946637 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.201864 -0.625309 0.753817 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.101942 -0.625316 0.773684 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.000027 -0.979855 0.199708 +vn -0.000016 -0.625302 0.780383 +vn -0.054866 -0.548214 0.834537 +vn 0.000012 -0.996795 -0.079997 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn -0.013125 -0.979860 0.199252 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.201864 -0.625309 0.753817 +vn -0.026105 -0.979864 0.197952 +vn -0.101942 -0.625316 0.773684 +vn -0.163052 -0.548348 0.820200 +vn 0.010461 -0.996795 -0.079312 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn -0.038954 -0.979864 0.195830 +vn -0.051676 -0.979859 0.192887 +vn -0.489963 -0.198913 0.848746 +vn -0.390094 -0.625314 0.675876 +vn -0.369902 -0.548374 0.749972 +vn -0.379146 -0.136670 0.915188 +vn -0.298790 -0.625312 0.720908 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.051676 -0.979859 0.192887 +vn -0.201864 -0.625309 0.753817 +vn -0.268920 -0.548039 0.792045 +vn 0.020704 -0.996795 -0.077272 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn -0.064229 -0.979856 0.189096 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.390094 -0.625314 0.675876 +vn -0.076475 -0.979861 0.184454 +vn -0.298790 -0.625312 0.720908 +vn -0.369902 -0.548374 0.749972 +vn 0.030640 -0.996795 -0.073898 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn -0.088341 -0.979865 0.179057 +vn -0.099830 -0.979863 0.172922 +vn -0.559013 0.035015 0.828420 +vn -0.520588 0.054246 0.852083 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.848748 -0.198912 0.489960 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.692977 -0.198918 0.692975 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551819 -0.625315 0.551794 +vn -0.551523 -0.548295 0.628645 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.475140 -0.625305 0.619061 +vn -0.099830 -0.979863 0.172922 +vn -0.390094 -0.625314 0.675876 +vn -0.464597 -0.548113 0.695501 +vn 0.039999 -0.996795 -0.069281 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn -0.110944 -0.979858 0.166042 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.551819 -0.625315 0.551794 +vn -0.121608 -0.979857 0.158406 +vn -0.475140 -0.625305 0.619061 +vn -0.551523 -0.548295 0.628645 +vn 0.048715 -0.996795 -0.063453 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn -0.131702 -0.979863 0.150080 +vn -0.141203 -0.979865 0.141164 +vn -0.848748 -0.198912 0.489960 +vn -0.675893 -0.625315 0.390065 +vn -0.695513 -0.548117 0.464574 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.619082 -0.625304 0.475112 +vn -0.141203 -0.979865 0.141164 +vn -0.551819 -0.625315 0.551794 +vn -0.628661 -0.548296 0.551504 +vn 0.056577 -0.996795 -0.056559 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn -0.150116 -0.979863 0.131661 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.675893 -0.625315 0.390065 +vn -0.158439 -0.979857 0.121565 +vn -0.619082 -0.625304 0.475112 +vn -0.695513 -0.548117 0.464574 +vn 0.063469 -0.996795 -0.048696 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn -0.166073 -0.979858 0.110900 +vn -0.172949 -0.979863 0.099784 +vn -0.959759 -0.214953 0.180714 +vn -0.972486 0.075824 0.220276 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.787262 -0.610234 0.088501 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.720921 -0.625312 0.298759 +vn -0.172949 -0.979863 0.099784 +vn -0.675893 -0.625315 0.390065 +vn -0.749983 -0.548375 0.369880 +vn 0.069293 -0.996795 -0.039977 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn -0.179081 -0.979865 0.088293 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.787262 -0.610234 0.088501 +vn -0.184475 -0.979861 0.076425 +vn -0.720921 -0.625312 0.298759 +vn -0.792052 -0.548040 0.268898 +vn 0.073908 -0.996795 -0.030617 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn -0.189113 -0.979856 0.064178 +vn -0.217514 -0.975719 0.025702 +vn -0.059975 -0.994232 0.088919 +vn 0.079340 -0.996763 -0.012975 +vn -0.217514 -0.975719 0.025702 +vn 0.003582 0.119290 0.992853 +vn -0.493340 0.119288 0.861618 +vn 0.003282 0.112908 0.993600 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn -0.494767 0.102956 0.862905 +vn 0.500192 0.089907 0.861234 +vn 0.499945 0.102956 0.859916 +vn 0.002990 0.102958 0.994681 +vn 0.522059 0.054243 0.851183 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.002546 0.089909 0.995947 +vn -0.495785 0.089908 0.863779 +vn 0.499657 0.112906 0.858834 +vn 0.499543 0.119288 0.858037 +vn 0.003582 0.119290 0.992853 +vn 0.499945 0.102956 0.859916 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.003282 0.112908 0.993600 +vn -0.493974 0.112906 0.862115 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.994681 0.102958 0.002990 +vn -0.495785 0.089908 0.863779 +vn -0.494767 0.102956 0.862905 +vn -0.859917 0.102956 0.499943 +vn -0.520588 0.054246 0.852083 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.861235 0.089907 0.500190 +vn -0.995947 0.089909 0.002546 +vn -0.493974 0.112906 0.862115 +vn -0.493340 0.119288 0.861618 +vn -0.858038 0.119288 0.499541 +vn -0.494767 0.102956 0.862905 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.858835 0.112906 0.499655 +vn -0.993600 0.112908 0.003282 +vn 0.860140 0.138592 0.490867 +vn 0.499499 0.138592 0.855157 +vn 0.860102 0.137445 0.491258 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.499366 0.128646 0.856787 +vn 0.992193 0.124653 -0.003810 +vn 0.991682 0.128649 -0.004054 +vn 0.860841 0.128646 0.492344 +vn 0.992853 0.119290 -0.003582 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.861162 0.124651 0.492811 +vn 0.499410 0.124651 0.857352 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.499299 0.134937 0.855858 +vn 0.991220 0.132159 -0.004236 +vn 0.990844 0.134939 -0.004460 +vn 0.860318 0.134936 0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.860531 0.132157 0.491956 +vn 0.499292 0.132157 0.856295 +vn 0.990337 0.138595 -0.004983 +vn 0.860140 0.138592 0.490867 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.860102 0.137445 0.491258 +vn 0.499269 0.137445 0.855476 +vn -0.857353 0.124650 0.499408 +vn -0.856788 0.128646 0.499364 +vn -0.991682 0.128649 0.004054 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn -0.492346 0.128646 0.860840 +vn 0.499410 0.124651 0.857352 +vn 0.499366 0.128646 0.856787 +vn 0.004054 0.128649 0.991682 +vn 0.499543 0.119288 0.858037 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.003810 0.124653 0.992193 +vn -0.492814 0.124651 0.861160 +vn -0.492814 0.124651 0.861160 +vn -0.492346 0.128646 0.860840 +vn -0.856788 0.128646 0.499364 +vn -0.493340 0.119288 0.861618 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.857353 0.124650 0.499408 +vn -0.992193 0.124653 0.003810 +vn 0.004983 0.138595 0.990337 +vn -0.490869 0.138592 0.860139 +vn 0.004625 0.137448 0.990498 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn -0.491576 0.134936 0.860317 +vn 0.499292 0.132157 0.856295 +vn 0.499299 0.134937 0.855858 +vn 0.004460 0.134939 0.990844 +vn 0.499366 0.128646 0.856787 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.004236 0.132159 0.991220 +vn -0.491957 0.132157 0.860530 +vn 0.499499 0.138592 0.855157 +vn 0.004983 0.138595 0.990337 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.004625 0.137448 0.990498 +vn -0.491260 0.137445 0.860100 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.990844 0.134939 0.004460 +vn -0.491957 0.132157 0.860530 +vn -0.491576 0.134936 0.860317 +vn -0.855859 0.134936 0.499297 +vn -0.492346 0.128646 0.860840 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.856296 0.132157 0.499291 +vn -0.991220 0.132159 0.004236 +vn -0.490869 0.138592 0.860139 +vn -0.855158 0.138592 0.499497 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.855477 0.137445 0.499267 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.990498 0.137448 0.004625 +vn -0.855477 0.137445 0.499267 +vn 0.990337 0.138595 -0.004983 +vn 0.990498 0.137448 -0.004625 +vn 0.855477 0.137445 -0.499267 +vn 0.992853 0.119290 -0.003582 +vn 0.993600 0.112908 -0.003282 +vn 0.858835 0.112906 -0.499655 +vn -0.499543 0.119288 -0.858037 +vn -0.499657 0.112906 -0.858834 +vn -0.862116 0.112906 -0.493972 +vn -0.679581 0.085468 -0.728605 +vn -0.865986 0.007573 -0.500011 +vn -0.864783 0.062737 -0.498211 +vn -0.864783 0.062737 -0.498211 +vn -0.559013 0.035015 -0.828420 +vn -0.679581 0.085468 -0.728605 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.998818 0.048476 0.003588 +vn -0.864783 0.062737 -0.498211 +vn -0.915190 -0.136671 -0.379143 +vn -0.946638 -0.198907 -0.253600 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.865986 0.007573 -0.500011 +vn -0.915190 -0.136671 -0.379143 +vn -0.982121 -0.136787 -0.129332 +vn -0.974045 -0.216081 0.067421 +vn -0.998818 0.048476 0.003588 +vn -0.998818 0.048476 0.003588 +vn -0.970776 0.085464 -0.224254 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.773684 -0.625316 -0.101943 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.834536 -0.548214 -0.054865 +vn -0.774567 -0.626221 0.088845 +vn -0.974045 -0.216081 0.067421 +vn -0.974045 -0.216081 0.067421 +vn -0.982121 -0.136787 -0.129332 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.197953 -0.979864 -0.026106 +vn -0.199250 -0.979861 -0.013125 +vn -0.834536 -0.548214 -0.054865 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.059975 -0.994232 0.088919 +vn -0.197953 -0.979864 -0.026106 +vn 0.079314 -0.996795 0.010461 +vn 0.079824 -0.996795 0.005260 +vn -0.753817 -0.625309 -0.201863 +vn -0.192889 -0.979859 -0.051676 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.195829 -0.979864 -0.038953 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn 0.079314 -0.996795 0.010461 +vn -0.192889 -0.979859 -0.051676 +vn 0.077272 -0.996795 0.020703 +vn 0.078460 -0.996795 0.015609 +vn -0.749973 -0.548375 -0.369898 +vn -0.720908 -0.625314 -0.298787 +vn -0.915190 -0.136671 -0.379143 +vn -0.915190 -0.136671 -0.379143 +vn -0.848748 -0.198912 -0.489960 +vn -0.749973 -0.548375 -0.369898 +vn -0.792045 -0.548040 -0.268918 +vn -0.753817 -0.625309 -0.201863 +vn -0.946638 -0.198907 -0.253600 +vn -0.946638 -0.198907 -0.253600 +vn -0.915190 -0.136671 -0.379143 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.184454 -0.979861 -0.076474 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn 0.077272 -0.996795 0.020703 +vn -0.184454 -0.979861 -0.076474 +vn 0.073898 -0.996795 0.030640 +vn 0.075746 -0.996795 0.025730 +vn -0.675878 -0.625313 -0.390093 +vn -0.172924 -0.979863 -0.099831 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.179057 -0.979865 -0.088341 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn 0.073898 -0.996795 0.030640 +vn -0.172924 -0.979863 -0.099831 +vn 0.069281 -0.996795 0.039999 +vn 0.071742 -0.996795 0.035397 +vn -0.559013 0.035015 -0.828420 +vn -0.489963 -0.198913 -0.848746 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.679581 0.085468 -0.728605 +vn -0.559013 0.035015 -0.828420 +vn -0.785908 -0.136554 -0.603077 +vn -0.848748 -0.198912 -0.489960 +vn -0.865986 0.007573 -0.500011 +vn -0.865986 0.007573 -0.500011 +vn -0.679581 0.085468 -0.728605 +vn -0.785908 -0.136554 -0.603077 +vn -0.628648 -0.548296 -0.551520 +vn -0.619062 -0.625306 -0.475137 +vn -0.785908 -0.136554 -0.603077 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.628648 -0.548296 -0.551520 +vn -0.695502 -0.548117 -0.464591 +vn -0.675878 -0.625313 -0.390093 +vn -0.848748 -0.198912 -0.489960 +vn -0.695502 -0.548117 -0.464591 +vn -0.848748 -0.198912 -0.489960 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.158405 -0.979857 -0.121607 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn 0.069281 -0.996795 0.039999 +vn -0.158405 -0.979857 -0.121607 +vn 0.063454 -0.996795 0.048715 +vn 0.066515 -0.996795 0.044445 +vn -0.551796 -0.625317 -0.551816 +vn -0.141165 -0.979865 -0.141202 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.150082 -0.979862 -0.131702 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn 0.063454 -0.996795 0.048715 +vn -0.141165 -0.979865 -0.141202 +vn 0.056560 -0.996795 0.056577 +vn 0.060129 -0.996795 0.052767 +vn -0.464580 -0.548113 -0.695513 +vn -0.475115 -0.625305 -0.619080 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.489963 -0.198913 -0.848746 +vn -0.464580 -0.548113 -0.695513 +vn -0.551508 -0.548294 -0.628659 +vn -0.551796 -0.625317 -0.551816 +vn -0.692977 -0.198918 -0.692975 +vn -0.551508 -0.548294 -0.628659 +vn -0.692977 -0.198918 -0.692975 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.121566 -0.979857 -0.158438 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn 0.056560 -0.996795 0.056577 +vn -0.121566 -0.979857 -0.158438 +vn 0.048696 -0.996795 0.063468 +vn 0.052748 -0.996795 0.060144 +vn -0.390067 -0.625315 -0.675892 +vn -0.099785 -0.979863 -0.172949 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.110900 -0.979858 -0.166071 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn 0.048696 -0.996795 0.063468 +vn -0.099785 -0.979863 -0.172949 +vn 0.039978 -0.996795 0.069293 +vn 0.044424 -0.996795 0.066528 +vn -0.499945 0.102956 -0.859916 +vn -0.500192 0.089907 -0.861234 +vn -0.863780 0.089908 -0.495782 +vn -0.862907 0.102956 -0.494765 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.998889 0.047128 0.000794 +vn -0.500192 0.089907 -0.861234 +vn -0.522059 0.054243 -0.851183 +vn -0.864783 0.062737 -0.498211 +vn -0.861619 0.119288 -0.493338 +vn -0.862116 0.112906 -0.493972 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.994681 0.102958 0.002990 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.862907 0.102956 -0.494765 +vn 0.863839 0.062737 -0.499846 +vn 0.998889 0.047128 -0.000794 +vn 0.998507 0.054619 0.000000 +vn 0.863839 0.062737 -0.499846 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 -0.224254 +vn 0.520588 0.054246 -0.852083 +vn 0.559013 0.035015 -0.828420 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn 0.520588 0.054246 -0.852083 +vn -0.224256 0.085466 -0.970775 +vn -0.559013 0.035015 -0.828420 +vn -0.522059 0.054243 -0.851183 +vn -0.522059 0.054243 -0.851183 +vn -0.000000 0.054620 -0.998507 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.253603 -0.198906 -0.946637 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn -0.379146 -0.136670 -0.915188 +vn -0.489963 -0.198913 -0.848746 +vn -0.559013 0.035015 -0.828420 +vn -0.379146 -0.136670 -0.915188 +vn -0.559013 0.035015 -0.828420 +vn -0.224256 0.085466 -0.970775 +vn -0.268901 -0.548039 -0.792052 +vn -0.298761 -0.625313 -0.720920 +vn -0.379146 -0.136670 -0.915188 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.369884 -0.548374 -0.749982 +vn -0.390067 -0.625315 -0.675892 +vn -0.489963 -0.198913 -0.848746 +vn -0.369884 -0.548374 -0.749982 +vn -0.489963 -0.198913 -0.848746 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.076426 -0.979861 -0.184474 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn 0.039978 -0.996795 0.069293 +vn -0.076426 -0.979861 -0.184474 +vn 0.030617 -0.996795 0.073907 +vn 0.035375 -0.996795 0.071753 +vn -0.201834 -0.625309 -0.753825 +vn -0.051625 -0.979859 -0.192902 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.064178 -0.979856 -0.189113 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn 0.030617 -0.996795 0.073907 +vn -0.051625 -0.979859 -0.192902 +vn 0.020680 -0.996795 0.077279 +vn 0.025707 -0.996795 0.075754 +vn -0.054845 -0.548214 -0.834538 +vn -0.101911 -0.625316 -0.773688 +vn -0.129333 -0.136787 -0.982121 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.163032 -0.548348 -0.820204 +vn -0.201834 -0.625309 -0.753825 +vn -0.253603 -0.198906 -0.946637 +vn -0.253603 -0.198906 -0.946637 +vn -0.129333 -0.136787 -0.982121 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.026053 -0.979864 -0.197959 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn 0.020680 -0.996795 0.077279 +vn -0.026053 -0.979864 -0.197959 +vn 0.010437 -0.996795 0.079315 +vn 0.015585 -0.996795 0.078466 +vn 0.000016 -0.625302 -0.780383 +vn 0.000027 -0.979855 -0.199708 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn -0.013072 -0.979860 -0.199255 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn 0.010437 -0.996795 0.079315 +vn 0.000027 -0.979855 -0.199708 +vn -0.000012 -0.996795 0.079997 +vn 0.005235 -0.996795 0.079826 +vn 0.379146 -0.136670 -0.915188 +vn 0.253603 -0.198906 -0.946637 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn 0.559013 0.035015 -0.828420 +vn 0.379146 -0.136670 -0.915188 +vn 0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.224256 0.085466 -0.970775 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.101942 -0.625316 -0.773684 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.054866 -0.548214 -0.834537 +vn 0.000016 -0.625302 -0.780383 +vn 0.000000 -0.198908 -0.980018 +vn 0.000000 -0.198908 -0.980018 +vn 0.129333 -0.136787 -0.982121 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.026105 -0.979864 -0.197952 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn -0.000012 -0.996795 0.079997 +vn 0.026105 -0.979864 -0.197952 +vn -0.010461 -0.996795 0.079312 +vn -0.005260 -0.996795 0.079825 +vn 0.201864 -0.625309 -0.753817 +vn 0.051676 -0.979859 -0.192887 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.038954 -0.979864 -0.195830 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn -0.010461 -0.996795 0.079312 +vn 0.051676 -0.979859 -0.192887 +vn -0.020704 -0.996795 0.077272 +vn -0.015609 -0.996795 0.078461 +vn 0.369902 -0.548374 -0.749972 +vn 0.298790 -0.625312 -0.720908 +vn 0.379146 -0.136670 -0.915188 +vn 0.379146 -0.136670 -0.915188 +vn 0.489963 -0.198913 -0.848746 +vn 0.369902 -0.548374 -0.749972 +vn 0.268920 -0.548039 -0.792045 +vn 0.201864 -0.625309 -0.753817 +vn 0.253603 -0.198906 -0.946637 +vn 0.253603 -0.198906 -0.946637 +vn 0.379146 -0.136670 -0.915188 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.076475 -0.979861 -0.184454 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn -0.020704 -0.996795 0.077272 +vn 0.076475 -0.979861 -0.184454 +vn -0.030640 -0.996795 0.073898 +vn -0.025730 -0.996795 0.075746 +vn 0.390094 -0.625314 -0.675876 +vn 0.099830 -0.979863 -0.172922 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.088341 -0.979865 -0.179057 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn -0.030640 -0.996795 0.073898 +vn 0.099830 -0.979863 -0.172922 +vn -0.039999 -0.996795 0.069281 +vn -0.035397 -0.996795 0.071742 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.679581 0.085468 -0.728605 +vn 0.679581 0.085468 -0.728605 +vn 0.559013 0.035015 -0.828420 +vn 0.863839 0.062737 -0.499846 +vn 0.785908 -0.136554 -0.603077 +vn 0.692977 -0.198918 -0.692975 +vn 0.679581 0.085468 -0.728605 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.865986 0.007573 -0.500011 +vn 0.603081 -0.136554 -0.785905 +vn 0.489963 -0.198913 -0.848746 +vn 0.559013 0.035015 -0.828420 +vn 0.559013 0.035015 -0.828420 +vn 0.679581 0.085468 -0.728605 +vn 0.603081 -0.136554 -0.785905 +vn 0.551523 -0.548295 -0.628645 +vn 0.475140 -0.625305 -0.619061 +vn 0.603081 -0.136554 -0.785905 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551523 -0.548295 -0.628645 +vn 0.464597 -0.548113 -0.695501 +vn 0.390094 -0.625314 -0.675876 +vn 0.489963 -0.198913 -0.848746 +vn 0.464597 -0.548113 -0.695501 +vn 0.489963 -0.198913 -0.848746 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.121608 -0.979857 -0.158406 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn -0.039999 -0.996795 0.069281 +vn 0.121608 -0.979857 -0.158406 +vn -0.048715 -0.996795 0.063453 +vn -0.044445 -0.996795 0.066514 +vn 0.551819 -0.625315 -0.551794 +vn 0.141203 -0.979865 -0.141164 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.131702 -0.979863 -0.150080 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn -0.048715 -0.996795 0.063453 +vn 0.141203 -0.979865 -0.141164 +vn -0.056577 -0.996795 0.056559 +vn -0.052767 -0.996795 0.060128 +vn 0.695513 -0.548117 -0.464574 +vn 0.619082 -0.625304 -0.475112 +vn 0.785908 -0.136554 -0.603077 +vn 0.785908 -0.136554 -0.603077 +vn 0.848748 -0.198912 -0.489960 +vn 0.695513 -0.548117 -0.464574 +vn 0.628661 -0.548296 -0.551504 +vn 0.551819 -0.625315 -0.551794 +vn 0.692977 -0.198918 -0.692975 +vn 0.628661 -0.548296 -0.551504 +vn 0.692977 -0.198918 -0.692975 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.158439 -0.979857 -0.121565 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn -0.056577 -0.996795 0.056559 +vn 0.158439 -0.979857 -0.121565 +vn -0.063469 -0.996795 0.048696 +vn -0.060145 -0.996795 0.052748 +vn 0.675893 -0.625315 -0.390065 +vn 0.172949 -0.979863 -0.099784 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.166073 -0.979858 -0.110900 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn -0.063469 -0.996795 0.048696 +vn 0.172949 -0.979863 -0.099784 +vn -0.069293 -0.996795 0.039977 +vn -0.066529 -0.996795 0.044425 +vn 0.998507 0.054619 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.970776 0.085464 -0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.915190 -0.136671 -0.379143 +vn 0.848748 -0.198912 -0.489960 +vn 0.865986 0.007573 -0.500011 +vn 0.915190 -0.136671 -0.379143 +vn 0.865986 0.007573 -0.500011 +vn 0.970776 0.085464 -0.224254 +vn 0.792052 -0.548040 -0.268898 +vn 0.720921 -0.625312 -0.298759 +vn 0.915190 -0.136671 -0.379143 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.749983 -0.548375 -0.369880 +vn 0.675893 -0.625315 -0.390065 +vn 0.848748 -0.198912 -0.489960 +vn 0.749983 -0.548375 -0.369880 +vn 0.848748 -0.198912 -0.489960 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.184475 -0.979861 -0.076425 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn -0.069293 -0.996795 0.039977 +vn 0.184475 -0.979861 -0.076425 +vn -0.073908 -0.996795 0.030617 +vn -0.071753 -0.996795 0.035375 +vn 0.753824 -0.625311 -0.201832 +vn 0.192902 -0.979859 -0.051624 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.189113 -0.979856 -0.064178 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn -0.073908 -0.996795 0.030617 +vn 0.192902 -0.979859 -0.051624 +vn -0.077279 -0.996795 0.020680 +vn -0.075754 -0.996795 0.025706 +vn 0.980018 -0.198907 0.000000 +vn 0.780383 -0.625302 0.000016 +vn 0.834538 -0.548214 -0.054844 +vn 0.834538 -0.548214 -0.054844 +vn 0.982121 -0.136787 -0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.820204 -0.548349 -0.163030 +vn 0.753824 -0.625311 -0.201832 +vn 0.946638 -0.198907 -0.253600 +vn 0.946638 -0.198907 -0.253600 +vn 0.982121 -0.136787 -0.129332 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.197959 -0.979864 -0.026053 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn -0.077279 -0.996795 0.020680 +vn 0.197959 -0.979864 -0.026053 +vn -0.079316 -0.996795 0.010437 +vn -0.078466 -0.996795 0.015585 +vn 0.780383 -0.625302 0.000016 +vn 0.199709 -0.979855 0.000026 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.199256 -0.979860 -0.013072 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn -0.079316 -0.996795 0.010437 +vn 0.199709 -0.979855 0.000026 +vn -0.079997 -0.996795 -0.000012 +vn -0.079827 -0.996795 0.005235 +vn 0.493340 0.119288 -0.861618 +vn 0.493974 0.112906 -0.862115 +vn -0.003282 0.112908 -0.993600 +vn 0.494767 0.102956 -0.862905 +vn 0.495785 0.089908 -0.863779 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn -0.002546 0.089909 -0.995947 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.522059 0.054243 -0.851183 +vn 0.495785 0.089908 -0.863779 +vn 0.520588 0.054246 -0.852083 +vn -0.000794 0.047128 -0.998889 +vn -0.003582 0.119290 -0.992853 +vn -0.003282 0.112908 -0.993600 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.499945 0.102956 -0.859916 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn -0.002990 0.102958 -0.994681 +vn 0.994681 0.102958 -0.002990 +vn 0.995947 0.089909 -0.002546 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.861235 0.089907 -0.500190 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.520588 0.054246 -0.852083 +vn 0.995947 0.089909 -0.002546 +vn 0.998889 0.047128 -0.000794 +vn 0.863839 0.062737 -0.499846 +vn 0.858038 0.119287 -0.499541 +vn 0.858835 0.112906 -0.499655 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.494767 0.102956 -0.862905 +vn 0.993600 0.112908 -0.003282 +vn 0.994681 0.102958 -0.002990 +vn 0.859917 0.102956 -0.499943 +vn -0.499499 0.138592 -0.855157 +vn -0.499269 0.137445 -0.855476 +vn -0.860102 0.137445 -0.491258 +vn -0.499366 0.128646 -0.856787 +vn -0.499410 0.124651 -0.857352 +vn -0.861162 0.124651 -0.492811 +vn -0.860841 0.128646 -0.492344 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.992853 0.119290 0.003582 +vn -0.499410 0.124651 -0.857352 +vn -0.499543 0.119288 -0.858037 +vn -0.861619 0.119288 -0.493338 +vn -0.499299 0.134937 -0.855858 +vn -0.499292 0.132157 -0.856295 +vn -0.860532 0.132157 -0.491955 +vn -0.860318 0.134936 -0.491574 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.991682 0.128649 0.004054 +vn -0.499292 0.132157 -0.856295 +vn -0.499366 0.128646 -0.856787 +vn -0.860841 0.128646 -0.492344 +vn -0.860140 0.138592 -0.490867 +vn -0.860102 0.137445 -0.491258 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.990844 0.134939 0.004460 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.860318 0.134936 -0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.992193 0.124653 -0.003810 +vn 0.857353 0.124650 -0.499408 +vn 0.492346 0.128646 -0.860840 +vn 0.492814 0.124651 -0.861160 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn -0.003810 0.124653 -0.992193 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.499543 0.119288 -0.858037 +vn 0.492814 0.124651 -0.861160 +vn 0.493340 0.119288 -0.861618 +vn -0.003582 0.119290 -0.992853 +vn 0.856788 0.128646 -0.499364 +vn 0.857353 0.124650 -0.499408 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.493340 0.119288 -0.861618 +vn 0.992193 0.124653 -0.003810 +vn 0.992853 0.119290 -0.003582 +vn 0.858038 0.119287 -0.499541 +vn 0.490869 0.138592 -0.860139 +vn 0.491260 0.137445 -0.860100 +vn -0.004625 0.137448 -0.990498 +vn 0.491576 0.134936 -0.860317 +vn 0.491957 0.132157 -0.860530 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn -0.004236 0.132159 -0.991220 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.499366 0.128646 -0.856787 +vn 0.491957 0.132157 -0.860530 +vn 0.492346 0.128646 -0.860840 +vn -0.004054 0.128649 -0.991682 +vn -0.004983 0.138595 -0.990337 +vn -0.004625 0.137448 -0.990498 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.499299 0.134937 -0.855858 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn -0.004460 0.134939 -0.990844 +vn 0.990844 0.134939 -0.004460 +vn 0.991220 0.132159 -0.004236 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.856296 0.132157 -0.499291 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.492346 0.128646 -0.860840 +vn 0.991220 0.132159 -0.004236 +vn 0.991682 0.128649 -0.004054 +vn 0.856788 0.128646 -0.499364 +vn 0.855158 0.138592 -0.499497 +vn 0.855477 0.137445 -0.499267 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.491576 0.134936 -0.860317 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.855859 0.134936 -0.499297 +vn -0.992853 0.119290 0.003582 +vn -0.993600 0.112908 0.003282 +vn -0.858835 0.112906 0.499655 +vn 0.499543 0.119288 0.858037 +vn 0.499657 0.112906 0.858834 +vn 0.862116 0.112906 0.493972 +vn 0.679581 0.085468 0.728605 +vn 0.865986 0.007573 0.500011 +vn 0.864783 0.062737 0.498211 +vn 0.864783 0.062737 0.498211 +vn 0.559013 0.035015 0.828420 +vn 0.679581 0.085468 0.728605 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.864783 0.062737 0.498211 +vn 0.915190 -0.136671 0.379143 +vn 0.946638 -0.198907 0.253600 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.865986 0.007573 0.500011 +vn 0.915190 -0.136671 0.379143 +vn 0.982121 -0.136787 0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 0.224254 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.773684 -0.625316 0.101943 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.834536 -0.548215 0.054865 +vn 0.780383 -0.625302 0.000016 +vn 0.980018 -0.198907 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 0.129332 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.197953 -0.979864 0.026106 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn -0.079997 -0.996795 -0.000012 +vn 0.197953 -0.979864 0.026106 +vn -0.079314 -0.996795 -0.010461 +vn -0.079824 -0.996795 -0.005260 +vn 0.753817 -0.625309 0.201863 +vn 0.192889 -0.979859 0.051676 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.195829 -0.979864 0.038953 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn -0.079314 -0.996795 -0.010461 +vn 0.192889 -0.979859 0.051676 +vn -0.077272 -0.996795 -0.020703 +vn -0.078460 -0.996795 -0.015609 +vn 0.749973 -0.548375 0.369898 +vn 0.720908 -0.625314 0.298787 +vn 0.915190 -0.136671 0.379143 +vn 0.915190 -0.136671 0.379143 +vn 0.848748 -0.198912 0.489960 +vn 0.749973 -0.548375 0.369898 +vn 0.792045 -0.548040 0.268918 +vn 0.753817 -0.625309 0.201863 +vn 0.946638 -0.198907 0.253600 +vn 0.946638 -0.198907 0.253600 +vn 0.915190 -0.136671 0.379143 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.184454 -0.979861 0.076474 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn -0.077272 -0.996795 -0.020703 +vn 0.184454 -0.979861 0.076474 +vn -0.073898 -0.996795 -0.030640 +vn -0.075746 -0.996795 -0.025730 +vn 0.675878 -0.625313 0.390093 +vn 0.172924 -0.979863 0.099831 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.179057 -0.979865 0.088341 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn -0.073898 -0.996795 -0.030640 +vn 0.172924 -0.979863 0.099831 +vn -0.069281 -0.996795 -0.039999 +vn -0.071742 -0.996795 -0.035397 +vn 0.603081 -0.136554 0.785905 +vn 0.692977 -0.198918 0.692975 +vn 0.679581 0.085468 0.728605 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.559013 0.035015 0.828420 +vn 0.785908 -0.136554 0.603077 +vn 0.848748 -0.198912 0.489960 +vn 0.865986 0.007573 0.500011 +vn 0.865986 0.007573 0.500011 +vn 0.679581 0.085468 0.728605 +vn 0.785908 -0.136554 0.603077 +vn 0.628648 -0.548296 0.551520 +vn 0.619062 -0.625306 0.475137 +vn 0.785908 -0.136554 0.603077 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.628648 -0.548296 0.551520 +vn 0.695502 -0.548117 0.464591 +vn 0.675878 -0.625313 0.390093 +vn 0.848748 -0.198912 0.489960 +vn 0.695502 -0.548117 0.464591 +vn 0.848748 -0.198912 0.489960 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.158405 -0.979857 0.121607 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn -0.069281 -0.996795 -0.039999 +vn 0.158405 -0.979857 0.121607 +vn -0.063454 -0.996795 -0.048715 +vn -0.066515 -0.996795 -0.044445 +vn 0.551796 -0.625317 0.551816 +vn 0.141165 -0.979865 0.141202 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.150082 -0.979862 0.131702 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn -0.063454 -0.996795 -0.048715 +vn 0.141165 -0.979865 0.141202 +vn -0.056560 -0.996795 -0.056577 +vn -0.060129 -0.996795 -0.052767 +vn 0.464580 -0.548113 0.695513 +vn 0.475115 -0.625305 0.619080 +vn 0.603081 -0.136554 0.785905 +vn 0.603081 -0.136554 0.785905 +vn 0.489963 -0.198913 0.848746 +vn 0.464580 -0.548113 0.695513 +vn 0.551508 -0.548294 0.628659 +vn 0.551796 -0.625317 0.551816 +vn 0.692977 -0.198918 0.692975 +vn 0.551508 -0.548294 0.628659 +vn 0.692977 -0.198918 0.692975 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.121566 -0.979857 0.158438 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn -0.056560 -0.996795 -0.056577 +vn 0.121566 -0.979857 0.158438 +vn -0.048696 -0.996795 -0.063468 +vn -0.052748 -0.996795 -0.060144 +vn 0.390067 -0.625315 0.675892 +vn 0.099785 -0.979863 0.172949 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.110900 -0.979858 0.166071 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn -0.048696 -0.996795 -0.063468 +vn 0.099785 -0.979863 0.172949 +vn -0.039978 -0.996795 -0.069293 +vn -0.044424 -0.996795 -0.066528 +vn 0.499945 0.102956 0.859916 +vn 0.500192 0.089907 0.861234 +vn 0.863780 0.089908 0.495782 +vn 0.862907 0.102956 0.494765 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.998889 0.047128 -0.000794 +vn 0.500192 0.089907 0.861234 +vn 0.522059 0.054243 0.851183 +vn 0.864783 0.062737 0.498211 +vn 0.861619 0.119288 0.493338 +vn 0.862116 0.112906 0.493972 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.994681 0.102958 -0.002990 +vn 0.499657 0.112906 0.858834 +vn 0.499945 0.102956 0.859916 +vn 0.862907 0.102956 0.494765 +vn -0.863839 0.062737 0.499846 +vn -0.998889 0.047128 0.000794 +vn -0.998818 0.048476 0.003588 +vn -0.863839 0.062737 0.499846 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.520588 0.054246 0.852083 +vn -0.559013 0.035015 0.828420 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn -0.520588 0.054246 0.852083 +vn 0.224256 0.085466 0.970775 +vn 0.559013 0.035015 0.828420 +vn 0.522059 0.054243 0.851183 +vn 0.522059 0.054243 0.851183 +vn 0.000000 0.054620 0.998507 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.253603 -0.198906 0.946637 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn 0.379146 -0.136670 0.915188 +vn 0.489963 -0.198913 0.848746 +vn 0.559013 0.035015 0.828420 +vn 0.379146 -0.136670 0.915188 +vn 0.559013 0.035015 0.828420 +vn 0.224256 0.085466 0.970775 +vn 0.268901 -0.548039 0.792052 +vn 0.298761 -0.625313 0.720920 +vn 0.379146 -0.136670 0.915188 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.369884 -0.548374 0.749982 +vn 0.390067 -0.625315 0.675892 +vn 0.489963 -0.198913 0.848746 +vn 0.369884 -0.548374 0.749982 +vn 0.489963 -0.198913 0.848746 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.076426 -0.979861 0.184474 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn -0.039978 -0.996795 -0.069293 +vn 0.076426 -0.979861 0.184474 +vn -0.030617 -0.996795 -0.073907 +vn -0.035375 -0.996795 -0.071753 +vn 0.201834 -0.625309 0.753825 +vn 0.051625 -0.979859 0.192902 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.064178 -0.979856 0.189113 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn -0.030617 -0.996795 -0.073907 +vn 0.051625 -0.979859 0.192902 +vn -0.020680 -0.996795 -0.077279 +vn -0.025707 -0.996795 -0.075754 +vn 0.054845 -0.548214 0.834538 +vn 0.101911 -0.625316 0.773688 +vn 0.129333 -0.136787 0.982121 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.163032 -0.548348 0.820204 +vn 0.201834 -0.625309 0.753825 +vn 0.253603 -0.198906 0.946637 +vn 0.253603 -0.198906 0.946637 +vn 0.129333 -0.136787 0.982121 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.026053 -0.979864 0.197959 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn -0.020680 -0.996795 -0.077279 +vn 0.026053 -0.979864 0.197959 +vn -0.010437 -0.996795 -0.079315 +vn -0.015585 -0.996795 -0.078466 +vn -0.000016 -0.625302 0.780383 +vn -0.000027 -0.979855 0.199708 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn 0.013072 -0.979860 0.199255 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn -0.010437 -0.996795 -0.079315 +vn -0.000027 -0.979855 0.199708 +vn 0.000012 -0.996795 -0.079997 +vn -0.005235 -0.996795 -0.079826 +vn -0.379146 -0.136670 0.915188 +vn -0.253603 -0.198906 0.946637 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn -0.559013 0.035015 0.828420 +vn -0.379146 -0.136670 0.915188 +vn -0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn -0.224256 0.085466 0.970775 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.101942 -0.625316 0.773684 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.054866 -0.548214 0.834537 +vn -0.000016 -0.625302 0.780383 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 -0.198908 0.980018 +vn -0.129333 -0.136787 0.982121 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.026105 -0.979864 0.197952 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn 0.000012 -0.996795 -0.079997 +vn -0.026105 -0.979864 0.197952 +vn 0.010461 -0.996795 -0.079312 +vn 0.005260 -0.996795 -0.079825 +vn -0.201864 -0.625309 0.753817 +vn -0.051676 -0.979859 0.192887 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.038954 -0.979864 0.195830 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn 0.010461 -0.996795 -0.079312 +vn -0.051676 -0.979859 0.192887 +vn 0.020704 -0.996795 -0.077272 +vn 0.015609 -0.996795 -0.078461 +vn -0.369902 -0.548374 0.749972 +vn -0.298790 -0.625312 0.720908 +vn -0.379146 -0.136670 0.915188 +vn -0.379146 -0.136670 0.915188 +vn -0.489963 -0.198913 0.848746 +vn -0.369902 -0.548374 0.749972 +vn -0.268920 -0.548039 0.792045 +vn -0.201864 -0.625309 0.753817 +vn -0.253603 -0.198906 0.946637 +vn -0.253603 -0.198906 0.946637 +vn -0.379146 -0.136670 0.915188 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.076475 -0.979861 0.184454 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn 0.020704 -0.996795 -0.077272 +vn -0.076475 -0.979861 0.184454 +vn 0.030640 -0.996795 -0.073898 +vn 0.025730 -0.996795 -0.075746 +vn -0.390094 -0.625314 0.675876 +vn -0.099830 -0.979863 0.172922 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.088341 -0.979865 0.179057 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn 0.030640 -0.996795 -0.073898 +vn -0.099830 -0.979863 0.172922 +vn 0.039999 -0.996795 -0.069281 +vn 0.035397 -0.996795 -0.071742 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.679581 0.085468 0.728605 +vn -0.679581 0.085468 0.728605 +vn -0.559013 0.035015 0.828420 +vn -0.863839 0.062737 0.499846 +vn -0.785908 -0.136554 0.603077 +vn -0.692977 -0.198918 0.692975 +vn -0.679581 0.085468 0.728605 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.865986 0.007573 0.500011 +vn -0.603081 -0.136554 0.785905 +vn -0.489963 -0.198913 0.848746 +vn -0.559013 0.035015 0.828420 +vn -0.559013 0.035015 0.828420 +vn -0.679581 0.085468 0.728605 +vn -0.603081 -0.136554 0.785905 +vn -0.551523 -0.548295 0.628645 +vn -0.475140 -0.625305 0.619061 +vn -0.603081 -0.136554 0.785905 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551523 -0.548295 0.628645 +vn -0.464597 -0.548113 0.695501 +vn -0.390094 -0.625314 0.675876 +vn -0.489963 -0.198913 0.848746 +vn -0.464597 -0.548113 0.695501 +vn -0.489963 -0.198913 0.848746 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.121608 -0.979857 0.158406 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn 0.039999 -0.996795 -0.069281 +vn -0.121608 -0.979857 0.158406 +vn 0.048715 -0.996795 -0.063453 +vn 0.044445 -0.996795 -0.066514 +vn -0.551819 -0.625315 0.551794 +vn -0.141203 -0.979865 0.141164 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.131702 -0.979863 0.150080 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn 0.048715 -0.996795 -0.063453 +vn -0.141203 -0.979865 0.141164 +vn 0.056577 -0.996795 -0.056559 +vn 0.052767 -0.996795 -0.060128 +vn -0.695513 -0.548117 0.464574 +vn -0.619082 -0.625304 0.475112 +vn -0.785908 -0.136554 0.603077 +vn -0.785908 -0.136554 0.603077 +vn -0.848748 -0.198912 0.489960 +vn -0.695513 -0.548117 0.464574 +vn -0.628661 -0.548296 0.551504 +vn -0.551819 -0.625315 0.551794 +vn -0.692977 -0.198918 0.692975 +vn -0.628661 -0.548296 0.551504 +vn -0.692977 -0.198918 0.692975 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.158439 -0.979857 0.121565 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn 0.056577 -0.996795 -0.056559 +vn -0.158439 -0.979857 0.121565 +vn 0.063469 -0.996795 -0.048696 +vn 0.060145 -0.996795 -0.052748 +vn -0.675893 -0.625315 0.390065 +vn -0.172949 -0.979863 0.099784 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.166073 -0.979858 0.110900 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn 0.063469 -0.996795 -0.048696 +vn -0.172949 -0.979863 0.099784 +vn 0.069293 -0.996795 -0.039977 +vn 0.066529 -0.996795 -0.044425 +vn -0.998818 0.048476 0.003588 +vn -0.974045 -0.216081 0.067421 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.848748 -0.198912 0.489960 +vn -0.865986 0.007573 0.500011 +vn -0.915190 -0.136671 0.379143 +vn -0.865986 0.007573 0.500011 +vn -0.972486 0.075824 0.220276 +vn -0.792052 -0.548040 0.268898 +vn -0.720921 -0.625312 0.298759 +vn -0.915190 -0.136671 0.379143 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.749983 -0.548375 0.369880 +vn -0.675893 -0.625315 0.390065 +vn -0.848748 -0.198912 0.489960 +vn -0.749983 -0.548375 0.369880 +vn -0.848748 -0.198912 0.489960 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.184475 -0.979861 0.076425 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn 0.069293 -0.996795 -0.039977 +vn -0.184475 -0.979861 0.076425 +vn 0.073908 -0.996795 -0.030617 +vn 0.071753 -0.996795 -0.035375 +vn -0.787262 -0.610234 0.088501 +vn -0.217514 -0.975719 0.025702 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.189113 -0.979856 0.064178 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn 0.073908 -0.996795 -0.030617 +vn -0.217514 -0.975719 0.025702 +vn 0.079340 -0.996763 -0.012975 +vn 0.075754 -0.996795 -0.025706 +vn -0.959759 -0.214953 0.180714 +vn -0.974045 -0.216081 0.067421 +vn -0.774567 -0.626221 0.088845 +vn -0.787262 -0.610234 0.088501 +vn -0.959759 -0.214953 0.180714 +vn -0.059975 -0.994232 0.088919 +vn -0.217514 -0.975719 0.025702 +vn -0.787262 -0.610234 0.088501 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.059975 -0.994232 0.088919 +vn -0.959759 -0.214953 0.180714 +vn -0.959759 -0.214953 0.180714 +vn -0.774567 -0.626221 0.088845 +vn -0.195626 -0.976106 0.094593 +vn -0.493340 0.119288 0.861618 +vn -0.493974 0.112906 0.862115 +vn 0.003282 0.112908 0.993600 +vn -0.494767 0.102956 0.862905 +vn -0.495785 0.089908 0.863779 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn 0.002546 0.089909 0.995947 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.522059 0.054243 0.851183 +vn -0.495785 0.089908 0.863779 +vn -0.520588 0.054246 0.852083 +vn 0.000794 0.047128 0.998889 +vn 0.003582 0.119290 0.992853 +vn 0.003282 0.112908 0.993600 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.499945 0.102956 0.859916 +vn -0.493974 0.112906 0.862115 +vn -0.494767 0.102956 0.862905 +vn 0.002990 0.102958 0.994681 +vn -0.994681 0.102958 0.002990 +vn -0.995947 0.089909 0.002546 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.861235 0.089907 0.500190 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.520588 0.054246 0.852083 +vn -0.995947 0.089909 0.002546 +vn -0.998889 0.047128 0.000794 +vn -0.863839 0.062737 0.499846 +vn -0.858038 0.119288 0.499541 +vn -0.858835 0.112906 0.499655 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.494767 0.102956 0.862905 +vn -0.993600 0.112908 0.003282 +vn -0.994681 0.102958 0.002990 +vn -0.859917 0.102956 0.499943 +vn 0.499499 0.138592 0.855157 +vn 0.499269 0.137445 0.855476 +vn 0.860102 0.137445 0.491258 +vn 0.499366 0.128646 0.856787 +vn 0.499410 0.124651 0.857352 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.861162 0.124651 0.492811 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.992853 0.119290 -0.003582 +vn 0.499410 0.124651 0.857352 +vn 0.499543 0.119288 0.858037 +vn 0.861619 0.119288 0.493338 +vn 0.499299 0.134937 0.855858 +vn 0.499292 0.132157 0.856295 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.860531 0.132157 0.491956 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.991682 0.128649 -0.004054 +vn 0.499292 0.132157 0.856295 +vn 0.499366 0.128646 0.856787 +vn 0.860841 0.128646 0.492344 +vn 0.860140 0.138592 0.490867 +vn 0.860102 0.137445 0.491258 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.990844 0.134939 -0.004460 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.860318 0.134936 0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.992193 0.124653 0.003810 +vn -0.857353 0.124650 0.499408 +vn -0.492346 0.128646 0.860840 +vn -0.492814 0.124651 0.861160 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn 0.003810 0.124653 0.992193 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.499543 0.119288 0.858037 +vn -0.492814 0.124651 0.861160 +vn -0.493340 0.119288 0.861618 +vn 0.003582 0.119290 0.992853 +vn -0.856788 0.128646 0.499364 +vn -0.857353 0.124650 0.499408 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.493340 0.119288 0.861618 +vn -0.992193 0.124653 0.003810 +vn -0.992853 0.119290 0.003582 +vn -0.858038 0.119288 0.499541 +vn -0.490869 0.138592 0.860139 +vn -0.491260 0.137445 0.860100 +vn 0.004625 0.137448 0.990498 +vn -0.491576 0.134936 0.860317 +vn -0.491957 0.132157 0.860530 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn 0.004236 0.132159 0.991220 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.499366 0.128646 0.856787 +vn -0.491957 0.132157 0.860530 +vn -0.492346 0.128646 0.860840 +vn 0.004054 0.128649 0.991682 +vn 0.004983 0.138595 0.990337 +vn 0.004625 0.137448 0.990498 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.499299 0.134937 0.855858 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn 0.004460 0.134939 0.990844 +vn -0.990844 0.134939 0.004460 +vn -0.991220 0.132159 0.004236 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.856296 0.132157 0.499291 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.492346 0.128646 0.860840 +vn -0.991220 0.132159 0.004236 +vn -0.991682 0.128649 0.004054 +vn -0.856788 0.128646 0.499364 +vn -0.855158 0.138592 0.499497 +vn -0.855477 0.137445 0.499267 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.491576 0.134936 0.860317 +vn -0.990498 0.137448 0.004625 +vn -0.990844 0.134939 0.004460 +vn -0.855859 0.134936 0.499297 +s off +g glass:revolvedSurface2 +usemtl initialShadingGroup +f 481/1/1 2/2/2 482/3/3 +f 260/4/4 3/5/5 261/6/6 +f 220/7/7 6/8/8 221/9/9 +f 81/10/10 7/11/11 83/12/12 +f 11/13/13 10/14/14 46/15/15 +f 13/16/16 9/17/17 11/13/18 +f 14/18/19 33/19/20 35/20/21 +f 15/21/22 18/22/23 19/23/24 +f 18/22/25 28/24/26 30/25/27 +f 19/23/28 22/26/29 23/27/30 +f 23/27/31 22/26/32 26/28/33 +f 25/29/34 21/30/35 23/27/36 +f 1/31/37 25/29/38 26/28/39 +f 24/32/40 26/28/41 27/33/42 +f 31/34/43 30/25/44 28/24/45 +f 27/33/46 22/26/47 30/25/48 +f 20/35/49 27/33/50 31/34/51 +f 29/36/52 31/34/53 32/37/54 +f 33/19/55 41/38/56 43/39/57 +f 35/20/58 36/40/59 38/41/60 +f 39/42/61 38/41/62 36/40/63 +f 32/37/64 28/24/65 38/41/66 +f 16/43/67 32/37/68 39/42/69 +f 37/44/70 39/42/71 40/45/72 +f 44/46/73 43/39/74 41/38/75 +f 40/45/76 36/40/77 43/39/78 +f 34/47/79 40/45/80 44/46/81 +f 42/48/82 44/46/83 45/49/84 +f 64/50/85 49/51/86 48/52/87 +f 48/52/88 49/51/89 51/53/90 +f 49/51/91 57/54/92 59/55/93 +f 51/53/94 52/56/95 54/57/96 +f 55/58/97 54/57/98 52/56/99 +f 45/49/100 41/38/101 54/57/102 +f 12/59/103 45/49/104 55/58/105 +f 53/60/106 55/58/107 56/61/108 +f 60/62/109 59/55/110 57/54/111 +f 56/61/112 52/56/113 59/55/114 +f 50/63/115 56/61/116 60/62/117 +f 58/64/118 60/62/119 61/65/120 +f 62/66/121 70/67/122 72/68/123 +f 64/50/124 65/69/125 67/70/126 +f 68/71/127 67/70/128 65/69/129 +f 61/65/130 57/54/131 67/70/132 +f 47/72/133 61/65/134 68/71/135 +f 66/73/136 68/71/137 69/74/138 +f 73/75/139 72/68/140 70/67/141 +f 69/74/142 65/69/143 72/68/144 +f 63/76/145 69/74/146 73/75/147 +f 71/77/148 73/75/149 74/78/150 +f 77/79/151 76/80/152 79/81/153 +f 78/82/154 75/83/155 77/79/156 +f 9/17/157 78/82/158 79/81/159 +f 11/13/160 79/81/161 80/84/162 +f 82/85/163 5/86/164 81/10/165 +f 75/83/166 82/85/167 83/12/168 +f 77/79/169 83/12/170 84/87/171 +f 181/88/172 150/89/173 149/90/174 +f 90/91/175 89/92/176 87/93/177 +f 10/14/178 89/92/179 90/91/180 +f 90/91/181 106/94/182 108/95/183 +f 92/96/184 93/97/185 95/98/186 +f 93/97/187 101/99/188 103/100/189 +f 95/98/190 96/101/191 98/102/192 +f 99/103/193 98/102/194 96/101/195 +f 74/78/196 70/67/197 98/102/198 +f 8/104/199 74/78/200 99/103/201 +f 97/105/202 99/103/203 100/106/204 +f 104/107/205 103/100/206 101/99/207 +f 100/106/208 96/101/209 103/100/210 +f 94/108/211 100/106/212 104/107/213 +f 102/109/214 104/107/215 105/110/216 +f 106/94/217 114/111/218 116/112/219 +f 108/95/220 109/113/221 111/114/222 +f 112/115/223 111/114/224 109/113/225 +f 105/110/226 101/99/227 111/114/228 +f 91/116/229 105/110/230 112/115/231 +f 110/117/232 112/115/233 113/118/234 +f 117/119/235 116/112/236 114/111/237 +f 113/118/238 109/113/239 116/112/240 +f 107/120/241 113/118/242 117/119/243 +f 115/121/244 117/119/245 118/122/246 +f 119/123/247 135/124/248 137/125/249 +f 121/126/250 122/127/251 124/128/252 +f 122/127/253 130/129/254 132/130/255 +f 124/128/256 125/131/257 127/132/258 +f 128/133/259 127/132/260 125/131/261 +f 118/122/262 114/111/263 127/132/264 +f 88/134/265 118/122/266 128/133/267 +f 126/135/268 128/133/269 129/136/270 +f 133/137/271 132/130/272 130/129/273 +f 129/136/274 125/131/275 132/130/276 +f 123/138/277 129/136/278 133/137/279 +f 131/139/280 133/137/281 134/140/282 +f 135/124/283 143/141/284 145/142/285 +f 137/125/286 138/143/287 140/144/288 +f 141/145/289 140/144/290 138/143/291 +f 134/140/292 130/129/293 140/144/294 +f 120/146/295 134/140/296 141/145/297 +f 139/147/298 141/145/299 142/148/300 +f 146/149/301 145/142/302 143/141/303 +f 142/148/304 138/143/305 145/142/306 +f 136/150/307 142/148/308 146/149/309 +f 144/151/310 146/149/311 147/152/312 +f 119/123/313 87/93/314 149/90/315 +f 150/89/316 166/153/317 168/154/318 +f 152/155/319 153/156/320 155/157/321 +f 153/156/322 161/158/323 163/159/324 +f 155/157/325 156/160/326 158/161/327 +f 159/162/328 158/161/329 156/160/330 +f 147/152/331 143/141/332 158/161/333 +f 86/163/334 147/152/335 159/162/336 +f 157/164/337 159/162/338 160/165/339 +f 164/166/340 163/159/341 161/158/342 +f 160/165/343 156/160/344 163/159/345 +f 154/167/346 160/165/347 164/166/348 +f 162/168/349 164/166/350 165/169/351 +f 166/153/352 174/170/353 176/171/354 +f 168/154/355 169/172/356 171/173/357 +f 172/174/358 171/173/359 169/172/360 +f 165/169/361 161/158/362 171/173/363 +f 151/175/364 165/169/365 172/174/366 +f 170/176/367 172/174/368 173/177/369 +f 177/178/370 176/171/371 174/170/372 +f 173/177/373 169/172/374 176/171/375 +f 167/179/376 173/177/377 177/178/378 +f 175/180/379 177/178/380 178/181/381 +f 197/182/382 182/183/383 181/88/384 +f 181/88/385 182/183/386 184/184/387 +f 182/183/388 190/185/389 192/186/390 +f 184/184/391 185/187/392 187/188/393 +f 188/189/394 187/188/395 185/187/396 +f 178/181/397 174/170/398 187/188/399 +f 148/190/400 178/181/401 188/189/402 +f 186/191/403 188/189/404 189/192/405 +f 193/193/406 192/186/407 190/185/408 +f 189/192/409 185/187/410 192/186/411 +f 183/194/412 189/192/413 193/193/414 +f 191/195/415 193/193/416 194/196/417 +f 205/197/418 198/198/419 197/182/420 +f 197/182/421 198/198/422 200/199/423 +f 201/200/424 200/199/425 198/198/426 +f 194/196/427 190/185/428 200/199/429 +f 180/201/430 194/196/431 201/200/432 +f 199/202/433 201/200/434 202/203/435 +f 206/204/436 205/197/437 203/205/438 +f 202/203/439 198/198/440 205/197/441 +f 196/206/442 202/203/443 206/204/444 +f 204/207/445 206/204/446 207/208/447 +f 213/209/448 208/210/449 214/211/450 +f 211/212/451 210/213/452 209/214/453 +f 80/84/454 76/80/455 210/213/456 +f 10/14/457 80/84/458 211/212/459 +f 89/92/460 211/212/461 212/215/462 +f 7/11/463 213/209/464 84/87/465 +f 76/80/466 84/87/467 214/211/468 +f 210/213/469 214/211/470 215/216/471 +f 218/217/472 217/218/473 216/219/474 +f 212/215/475 209/214/476 217/218/477 +f 87/93/478 212/215/479 218/217/480 +f 149/90/481 218/217/482 219/220/483 +f 208/210/484 220/7/485 215/216/486 +f 209/214/487 215/216/488 221/9/489 +f 217/218/490 221/9/491 222/221/492 +f 236/222/493 223/223/494 238/224/495 +f 226/225/496 225/226/497 228/227/498 +f 227/228/499 224/229/500 226/225/501 +f 5/86/502 227/228/503 228/227/504 +f 81/10/505 228/227/506 229/230/507 +f 232/231/508 231/232/509 234/233/510 +f 233/234/511 230/235/512 232/231/513 +f 224/229/514 233/234/515 234/233/516 +f 226/225/517 234/233/518 235/236/519 +f 237/237/520 2/238/521 236/222/522 +f 230/235/523 237/237/524 238/224/525 +f 232/231/526 238/224/527 239/239/528 +f 246/240/529 245/241/530 240/242/531 +f 243/243/532 242/244/533 241/245/534 +f 229/230/535 225/226/536 242/244/537 +f 7/11/538 229/230/539 243/243/540 +f 213/209/541 243/243/542 244/246/543 +f 244/246/544 241/245/545 245/241/546 +f 208/210/547 244/246/548 246/240/549 +f 220/7/550 246/240/551 247/247/552 +f 253/248/553 248/249/554 254/250/555 +f 251/251/556 250/252/557 249/253/558 +f 235/236/559 231/232/560 250/252/561 +f 225/226/562 235/236/563 251/251/564 +f 242/244/565 251/251/566 252/254/567 +f 223/223/568 253/248/569 239/239/570 +f 231/232/571 239/239/572 254/250/573 +f 250/252/574 254/250/575 255/255/576 +f 258/256/577 257/257/578 256/258/579 +f 252/254/580 249/253/581 257/257/582 +f 241/245/583 252/254/584 258/256/585 +f 245/241/586 258/256/587 259/259/588 +f 248/249/589 260/4/590 255/255/591 +f 249/253/592 255/255/593 261/6/594 +f 257/257/595 261/6/596 262/260/597 +f 452/261/598 451/262/599 5/263/600 +f 330/264/601 264/265/602 331/266/603 +f 267/267/604 265/268/605 297/269/606 +f 179/270/607 85/271/608 267/267/609 +f 268/272/610 284/273/611 286/274/612 +f 270/275/613 271/276/614 273/277/615 +f 271/276/616 279/278/617 281/279/618 +f 273/277/619 274/280/620 276/281/621 +f 277/282/622 276/281/623 274/280/624 +f 207/208/625 203/205/626 276/281/627 +f 4/283/628 207/208/629 277/282/630 +f 275/284/631 277/282/632 278/285/633 +f 282/286/634 281/279/635 279/278/636 +f 278/285/637 274/280/638 281/279/639 +f 272/287/640 278/285/641 282/286/642 +f 280/288/643 282/286/644 283/289/645 +f 284/273/646 292/290/647 294/291/648 +f 286/274/649 287/292/650 289/293/651 +f 290/294/652 289/293/653 287/292/654 +f 283/289/655 279/278/656 289/293/657 +f 269/295/658 283/289/659 290/294/660 +f 288/296/661 290/294/662 291/297/663 +f 295/298/664 294/291/665 292/290/666 +f 291/297/667 287/292/668 294/291/669 +f 285/299/670 291/297/671 295/298/672 +f 293/300/673 295/298/674 296/301/675 +f 297/269/676 313/302/677 315/303/678 +f 299/304/679 300/305/680 302/306/681 +f 300/305/682 308/307/683 310/308/684 +f 302/306/685 303/309/686 305/310/687 +f 306/311/688 305/310/689 303/309/690 +f 296/301/691 292/290/692 305/310/693 +f 266/312/694 296/301/695 306/311/696 +f 304/313/697 306/311/698 307/314/699 +f 311/315/700 310/308/701 308/307/702 +f 307/314/703 303/309/704 310/308/705 +f 301/316/706 307/314/707 311/315/708 +f 309/317/709 311/315/710 312/318/711 +f 313/302/712 321/319/713 323/320/714 +f 315/303/715 316/321/716 318/322/717 +f 319/323/718 318/322/719 316/321/720 +f 312/318/721 308/307/722 318/322/723 +f 298/324/724 312/318/725 319/323/726 +f 317/325/727 319/323/728 320/326/729 +f 324/327/730 323/320/731 321/319/732 +f 320/326/733 316/321/734 323/320/735 +f 314/328/736 320/326/737 324/327/738 +f 322/329/739 324/327/740 325/330/741 +f 327/331/742 326/332/743 328/333/744 +f 219/220/745 216/219/746 327/331/747 +f 85/271/748 219/220/749 328/333/750 +f 267/267/751 328/333/752 329/334/753 +f 222/221/754 6/8/755 330/264/756 +f 216/219/757 222/221/758 331/266/759 +f 327/331/760 331/266/761 332/335/762 +f 427/336/763 397/337/764 396/338/765 +f 337/339/766 336/340/767 334/341/768 +f 265/268/769 336/340/770 337/339/771 +f 337/339/772 353/342/773 355/343/774 +f 339/344/775 340/345/776 342/346/777 +f 340/345/778 348/347/779 350/348/780 +f 342/346/781 343/349/782 345/350/783 +f 346/351/784 345/350/785 343/349/786 +f 325/330/787 321/319/788 345/350/789 +f 263/352/790 325/330/791 346/351/792 +f 344/353/793 346/351/794 347/354/795 +f 351/355/796 350/348/797 348/347/798 +f 347/354/799 343/349/800 350/348/801 +f 341/356/802 347/354/803 351/355/804 +f 349/357/805 351/355/806 352/358/807 +f 353/342/808 361/359/809 363/360/810 +f 355/343/811 356/361/812 358/362/813 +f 359/363/814 358/362/815 356/361/816 +f 352/358/817 348/347/818 358/362/819 +f 338/364/820 352/358/821 359/363/822 +f 357/365/823 359/363/824 360/366/825 +f 364/367/826 363/360/827 361/359/828 +f 360/366/829 356/361/830 363/360/831 +f 354/368/832 360/366/833 364/367/834 +f 362/369/835 364/367/836 365/370/837 +f 366/371/838 382/372/839 384/373/840 +f 368/374/841 369/375/842 371/376/843 +f 369/375/844 377/377/845 379/378/846 +f 371/376/847 372/379/848 374/380/849 +f 375/381/850 374/380/851 372/379/852 +f 365/370/853 361/359/854 374/380/855 +f 335/382/856 365/370/857 375/381/858 +f 373/383/859 375/381/860 376/384/861 +f 380/385/862 379/378/863 377/377/864 +f 376/384/865 372/379/866 379/378/867 +f 370/386/868 376/384/869 380/385/870 +f 378/387/871 380/385/872 381/388/873 +f 382/372/874 390/389/875 392/390/876 +f 384/373/877 385/391/878 387/392/879 +f 388/393/880 387/392/881 385/391/882 +f 381/388/883 377/377/884 387/392/885 +f 367/394/886 381/388/887 388/393/888 +f 386/395/889 388/393/890 389/396/891 +f 393/397/892 392/390/893 390/389/894 +f 389/396/895 385/391/896 392/390/897 +f 383/398/898 389/396/899 393/397/900 +f 391/399/901 393/397/902 394/400/903 +f 366/371/904 334/341/905 396/338/906 +f 397/337/907 413/401/908 415/402/909 +f 399/403/910 400/404/911 402/405/912 +f 400/404/913 408/406/914 410/407/915 +f 402/405/916 403/408/917 405/409/918 +f 406/410/919 405/409/920 403/408/921 +f 394/400/922 390/389/923 405/409/924 +f 333/411/925 394/400/926 406/410/927 +f 404/412/928 406/410/929 407/413/930 +f 411/414/931 410/407/932 408/406/933 +f 407/413/934 403/408/935 410/407/936 +f 401/415/937 407/413/938 411/414/939 +f 409/416/940 411/414/941 412/417/942 +f 413/401/943 421/418/944 423/419/945 +f 415/402/946 416/420/947 418/421/948 +f 419/422/949 418/421/950 416/420/951 +f 412/417/952 408/406/953 418/421/954 +f 398/423/955 412/417/956 419/422/957 +f 417/424/958 419/422/959 420/425/960 +f 424/426/961 423/419/962 421/418/963 +f 420/425/964 416/420/965 423/419/966 +f 414/427/967 420/425/968 424/426/969 +f 422/428/970 424/426/971 425/429/972 +f 428/430/973 427/336/974 13/431/975 +f 427/336/976 428/430/977 430/432/978 +f 428/430/979 436/433/980 438/434/981 +f 430/432/982 431/435/983 433/436/984 +f 434/437/985 433/436/986 431/435/987 +f 425/429/988 421/418/989 433/436/990 +f 395/438/991 425/429/992 434/437/993 +f 432/439/994 434/437/995 435/440/996 +f 439/441/997 438/434/998 436/433/999 +f 435/440/1000 431/435/1001 438/434/1002 +f 429/442/1003 435/440/1004 439/441/1005 +f 437/443/1006 439/441/1007 440/444/1008 +f 1/445/1009 426/446/1010 440/444/1011 +f 446/447/1012 441/448/1013 447/449/1014 +f 444/450/1015 443/451/1016 442/452/1017 +f 329/334/1018 326/332/1019 443/451/1020 +f 265/268/1021 329/334/1022 444/450/1023 +f 336/340/1024 444/450/1025 445/453/1026 +f 332/335/1027 264/265/1028 446/447/1029 +f 326/332/1030 332/335/1031 447/449/1032 +f 443/451/1033 447/449/1034 448/454/1035 +f 450/455/1036 449/456/1037 75/457/1038 +f 445/453/1039 442/452/1040 449/456/1041 +f 334/341/1042 445/453/1043 450/455/1044 +f 396/338/1045 450/455/1046 78/458/1047 +f 448/454/1048 441/448/1049 451/262/1050 +f 442/452/1051 448/454/1052 452/261/1053 +f 449/456/1054 452/261/1055 82/459/1056 +f 462/460/1057 453/461/1058 463/462/1059 +f 456/463/1060 455/464/1061 454/465/1062 +f 247/247/1063 240/242/1064 455/464/1065 +f 6/8/1066 247/247/1067 456/463/1068 +f 330/264/1069 456/463/1070 457/466/1071 +f 460/467/1072 459/468/1073 458/469/1074 +f 259/259/1075 256/258/1076 459/468/1077 +f 240/242/1078 259/259/1079 460/467/1080 +f 455/464/1081 460/467/1082 461/470/1083 +f 3/5/1084 462/460/1085 262/260/1086 +f 256/258/1087 262/260/1088 463/462/1089 +f 459/468/1090 463/462/1091 464/471/1092 +f 470/472/1093 469/473/1094 224/474/1095 +f 467/475/1096 466/476/1097 465/477/1098 +f 457/466/1099 454/465/1100 466/476/1101 +f 264/265/1102 457/466/1103 467/475/1104 +f 446/447/1105 467/475/1106 468/478/1107 +f 468/478/1108 465/477/1109 469/473/1110 +f 441/448/1111 468/478/1112 470/472/1113 +f 451/262/1114 470/472/1115 227/479/1116 +f 476/480/1117 471/481/1118 477/482/1119 +f 474/483/1120 473/484/1121 472/485/1122 +f 461/470/1123 458/469/1124 473/484/1125 +f 454/465/1126 461/470/1127 474/483/1128 +f 466/476/1129 474/483/1130 475/486/1131 +f 453/461/1132 476/480/1133 464/471/1134 +f 458/469/1135 464/471/1136 477/482/1137 +f 473/484/1138 477/482/1139 478/487/1140 +f 480/488/1141 479/489/1142 230/490/1143 +f 475/486/1144 472/485/1145 479/489/1146 +f 465/477/1147 475/486/1148 480/488/1149 +f 469/473/1150 480/488/1151 233/491/1152 +f 471/481/1153 481/1/1154 478/487/1155 +f 472/485/1156 478/487/1157 482/3/1158 +f 479/489/1159 482/3/1160 237/492/1161 +f 2/2/1162 237/492/1163 482/3/1164 +f 3/5/1165 262/260/1166 261/6/1167 +f 6/8/1168 222/221/1169 221/9/1170 +f 7/11/1171 84/87/1172 83/12/1173 +f 48/52/1174 14/18/1175 11/13/1176 +f 11/13/1177 46/15/1178 48/52/1179 +f 11/13/1180 14/18/1181 15/21/1182 +f 15/21/1183 13/16/1184 11/13/1185 +f 35/20/1186 18/22/1187 15/21/1188 +f 15/21/1189 14/18/1190 35/20/1191 +f 19/23/1192 17/493/1193 13/16/1194 +f 13/16/1195 15/21/1196 19/23/1197 +f 30/25/1198 22/26/1199 19/23/1200 +f 30/25/1201 19/23/1202 18/22/1203 +f 23/27/1204 21/30/1205 17/493/1206 +f 17/493/1207 19/23/1208 23/27/1209 +f 22/26/1210 27/33/1211 26/28/1212 +f 23/27/1213 26/28/1214 25/29/1215 +f 26/28/1216 24/32/1217 1/31/1218 +f 27/33/1219 20/35/1220 24/32/1221 +f 28/24/1222 32/37/1223 31/34/1224 +f 30/25/1225 31/34/1226 27/33/1227 +f 31/34/1228 29/36/1229 20/35/1230 +f 32/37/1231 16/43/1232 29/36/1233 +f 43/39/1234 36/40/1235 35/20/1236 +f 35/20/1237 33/19/1238 43/39/1239 +f 38/41/1240 28/24/1241 18/22/1242 +f 18/22/1243 35/20/1244 38/41/1245 +f 36/40/1246 40/45/1247 39/42/1248 +f 38/41/1249 39/42/1250 32/37/1251 +f 39/42/1252 37/44/1253 16/43/1254 +f 40/45/1255 34/47/1256 37/44/1257 +f 41/38/1258 45/49/1259 44/46/1260 +f 43/39/1261 44/46/1262 40/45/1263 +f 44/46/1264 42/48/1265 34/47/1266 +f 45/49/1267 12/59/1268 42/48/1269 +f 46/15/1270 62/66/1271 64/50/1272 +f 64/50/1273 48/52/1274 46/15/1275 +f 51/53/1276 33/19/1277 14/18/1278 +f 14/18/1279 48/52/1280 51/53/1281 +f 59/55/1282 52/56/1283 51/53/1284 +f 51/53/1285 49/51/1286 59/55/1287 +f 54/57/1288 41/38/1289 33/19/1290 +f 54/57/1291 33/19/1292 51/53/1293 +f 52/56/1294 56/61/1295 55/58/1296 +f 54/57/1297 55/58/1298 45/49/1299 +f 55/58/1300 53/60/1301 12/59/1302 +f 56/61/1303 50/63/1304 53/60/1305 +f 57/54/1306 61/65/1307 60/62/1308 +f 59/55/1309 60/62/1310 56/61/1311 +f 60/62/1312 58/64/1313 50/63/1314 +f 61/65/1315 47/72/1316 58/64/1317 +f 72/68/1318 65/69/1319 64/50/1320 +f 64/50/1321 62/66/1322 72/68/1323 +f 67/70/1324 57/54/1325 49/51/1326 +f 67/70/1327 49/51/1328 64/50/1329 +f 65/69/1330 69/74/1331 68/71/1332 +f 67/70/1333 68/71/1334 61/65/1335 +f 68/71/1336 66/73/1337 47/72/1338 +f 69/74/1339 63/76/1340 66/73/1341 +f 70/67/1342 74/78/1343 73/75/1344 +f 72/68/1345 73/75/1346 69/74/1347 +f 73/75/1348 71/77/1349 63/76/1350 +f 74/78/1351 8/104/1352 71/77/1353 +f 76/80/1354 80/84/1355 79/81/1356 +f 77/79/1357 79/81/1358 78/82/1359 +f 79/81/1360 11/13/1361 9/17/1362 +f 80/84/1363 10/14/1364 11/13/1365 +f 81/10/1366 83/12/1367 82/85/1368 +f 83/12/1369 77/79/1370 75/83/1371 +f 84/87/1372 76/80/1373 77/79/1374 +f 149/90/1375 85/271/1376 179/270/1377 +f 149/90/1378 179/270/1379 181/88/1380 +f 87/93/1381 119/123/1382 121/126/1383 +f 121/126/1384 90/91/1385 87/93/1386 +f 92/96/1387 46/15/1388 10/14/1389 +f 10/14/1390 90/91/1391 92/96/1392 +f 108/95/1393 93/97/1394 92/96/1395 +f 108/95/1396 92/96/1397 90/91/1398 +f 95/98/1399 62/66/1400 46/15/1401 +f 95/98/1402 46/15/1403 92/96/1404 +f 103/100/1405 96/101/1406 95/98/1407 +f 103/100/1408 95/98/1409 93/97/1410 +f 98/102/1411 70/67/1412 62/66/1413 +f 98/102/1414 62/66/1415 95/98/1416 +f 96/101/1417 100/106/1418 99/103/1419 +f 98/102/1420 99/103/1421 74/78/1422 +f 99/103/1423 97/105/1424 8/104/1425 +f 100/106/1426 94/108/1427 97/105/1428 +f 101/99/1429 105/110/1430 104/107/1431 +f 103/100/1432 104/107/1433 100/106/1434 +f 104/107/1435 102/109/1436 94/108/1437 +f 105/110/1438 91/116/1439 102/109/1440 +f 116/112/1441 109/113/1442 108/95/1443 +f 116/112/1444 108/95/1445 106/94/1446 +f 111/114/1447 101/99/1448 93/97/1449 +f 93/97/1450 108/95/1451 111/114/1452 +f 109/113/1453 113/118/1454 112/115/1455 +f 111/114/1456 112/115/1457 105/110/1458 +f 112/115/1459 110/117/1460 91/116/1461 +f 113/118/1462 107/120/1463 110/117/1464 +f 114/111/1465 118/122/1466 117/119/1467 +f 116/112/1468 117/119/1469 113/118/1470 +f 117/119/1471 115/121/1472 107/120/1473 +f 118/122/1474 88/134/1475 115/121/1476 +f 137/125/1477 122/127/1478 121/126/1479 +f 121/126/1480 119/123/1481 137/125/1482 +f 124/128/1483 106/94/1484 90/91/1485 +f 90/91/1486 121/126/1487 124/128/1488 +f 132/130/1489 125/131/1490 124/128/1491 +f 132/130/1492 124/128/1493 122/127/1494 +f 127/132/1495 114/111/1496 106/94/1497 +f 106/94/1498 124/128/1499 127/132/1500 +f 125/131/1501 129/136/1502 128/133/1503 +f 127/132/1504 128/133/1505 118/122/1506 +f 128/133/1507 126/135/1508 88/134/1509 +f 129/136/1510 123/138/1511 126/135/1512 +f 130/129/1513 134/140/1514 133/137/1515 +f 132/130/1516 133/137/1517 129/136/1518 +f 133/137/1519 131/139/1520 123/138/1521 +f 134/140/1522 120/146/1523 131/139/1524 +f 145/142/1525 138/143/1526 137/125/1527 +f 137/125/1528 135/124/1529 145/142/1530 +f 140/144/1531 130/129/1532 122/127/1533 +f 122/127/1534 137/125/1535 140/144/1536 +f 138/143/1537 142/148/1538 141/145/1539 +f 140/144/1540 141/145/1541 134/140/1542 +f 141/145/1543 139/147/1544 120/146/1545 +f 142/148/1546 136/150/1547 139/147/1548 +f 143/141/1549 147/152/1550 146/149/1551 +f 145/142/1552 146/149/1553 142/148/1554 +f 146/149/1555 144/151/1556 136/150/1557 +f 147/152/1558 86/163/1559 144/151/1560 +f 149/90/1561 150/89/1562 152/155/1563 +f 152/155/1564 119/123/1565 149/90/1566 +f 168/154/1567 153/156/1568 152/155/1569 +f 168/154/1570 152/155/1571 150/89/1572 +f 155/157/1573 135/124/1574 119/123/1575 +f 119/123/1576 152/155/1577 155/157/1578 +f 163/159/1579 156/160/1580 155/157/1581 +f 155/157/1582 153/156/1583 163/159/1584 +f 158/161/1585 143/141/1586 135/124/1587 +f 158/161/1588 135/124/1589 155/157/1590 +f 156/160/1591 160/165/1592 159/162/1593 +f 158/161/1594 159/162/1595 147/152/1596 +f 159/162/1597 157/164/1598 86/163/1599 +f 160/165/1600 154/167/1601 157/164/1602 +f 161/158/1603 165/169/1604 164/166/1605 +f 163/159/1606 164/166/1607 160/165/1608 +f 164/166/1609 162/168/1610 154/167/1611 +f 165/169/1612 151/175/1613 162/168/1614 +f 176/171/1615 169/172/1616 168/154/1617 +f 168/154/1618 166/153/1619 176/171/1620 +f 171/173/1621 161/158/1622 153/156/1623 +f 171/173/1624 153/156/1625 168/154/1626 +f 169/172/1627 173/177/1628 172/174/1629 +f 171/173/1630 172/174/1631 165/169/1632 +f 172/174/1633 170/176/1634 151/175/1635 +f 173/177/1636 167/179/1637 170/176/1638 +f 174/170/1639 178/181/1640 177/178/1641 +f 176/171/1642 177/178/1643 173/177/1644 +f 177/178/1645 175/180/1646 167/179/1647 +f 178/181/1648 148/190/1649 175/180/1650 +f 179/270/1651 195/494/1652 197/182/1653 +f 197/182/1654 181/88/1655 179/270/1656 +f 184/184/1657 166/153/1658 150/89/1659 +f 184/184/1660 150/89/1661 181/88/1662 +f 192/186/1663 185/187/1664 184/184/1665 +f 192/186/1666 184/184/1667 182/183/1668 +f 187/188/1669 174/170/1670 166/153/1671 +f 187/188/1672 166/153/1673 184/184/1674 +f 185/187/1675 189/192/1676 188/189/1677 +f 187/188/1678 188/189/1679 178/181/1680 +f 188/189/1681 186/191/1682 148/190/1683 +f 189/192/1684 183/194/1685 186/191/1686 +f 190/185/1687 194/196/1688 193/193/1689 +f 192/186/1690 193/193/1691 189/192/1692 +f 193/193/1693 191/195/1694 183/194/1695 +f 194/196/1696 180/201/1697 191/195/1698 +f 195/494/1699 203/205/1700 205/197/1701 +f 205/197/1702 197/182/1703 195/494/1704 +f 200/199/1705 190/185/1706 182/183/1707 +f 182/183/1708 197/182/1709 200/199/1710 +f 198/198/1711 202/203/1712 201/200/1713 +f 200/199/1714 201/200/1715 194/196/1716 +f 201/200/1717 199/202/1718 180/201/1719 +f 202/203/1720 196/206/1721 199/202/1722 +f 203/205/1723 207/208/1724 206/204/1725 +f 205/197/1726 206/204/1727 202/203/1728 +f 206/204/1729 204/207/1730 196/206/1731 +f 207/208/1732 4/283/1733 204/207/1734 +f 208/210/1735 215/216/1736 214/211/1737 +f 209/214/1738 212/215/1739 211/212/1740 +f 210/213/1741 211/212/1742 80/84/1743 +f 211/212/1744 89/92/1745 10/14/1746 +f 212/215/1747 87/93/1748 89/92/1749 +f 213/209/1750 214/211/1751 84/87/1752 +f 214/211/1753 210/213/1754 76/80/1755 +f 215/216/1756 209/214/1757 210/213/1758 +f 216/219/1759 219/220/1760 218/217/1761 +f 217/218/1762 218/217/1763 212/215/1764 +f 218/217/1765 149/90/1766 87/93/1767 +f 219/220/1768 85/271/1769 149/90/1770 +f 220/7/1771 221/9/1772 215/216/1773 +f 221/9/1774 217/218/1775 209/214/1776 +f 222/221/1777 216/219/1778 217/218/1779 +f 223/223/1780 239/239/1781 238/224/1782 +f 225/226/1783 229/230/1784 228/227/1785 +f 226/225/1786 228/227/1787 227/228/1788 +f 228/227/1789 81/10/1790 5/86/1791 +f 229/230/1792 7/11/1793 81/10/1794 +f 231/232/1795 235/236/1796 234/233/1797 +f 232/231/1798 234/233/1799 233/234/1800 +f 234/233/1801 226/225/1802 224/229/1803 +f 235/236/1804 225/226/1805 226/225/1806 +f 236/222/1807 238/224/1808 237/237/1809 +f 238/224/1810 232/231/1811 230/235/1812 +f 239/239/1813 231/232/1814 232/231/1815 +f 240/242/1816 247/247/1817 246/240/1818 +f 241/245/1819 244/246/1820 243/243/1821 +f 242/244/1822 243/243/1823 229/230/1824 +f 243/243/1825 213/209/1826 7/11/1827 +f 244/246/1828 208/210/1829 213/209/1830 +f 245/241/1831 246/240/1832 244/246/1833 +f 246/240/1834 220/7/1835 208/210/1836 +f 247/247/1837 6/8/1838 220/7/1839 +f 248/249/1840 255/255/1841 254/250/1842 +f 249/253/1843 252/254/1844 251/251/1845 +f 250/252/1846 251/251/1847 235/236/1848 +f 251/251/1849 242/244/1850 225/226/1851 +f 252/254/1852 241/245/1853 242/244/1854 +f 253/248/1855 254/250/1856 239/239/1857 +f 254/250/1858 250/252/1859 231/232/1860 +f 255/255/1861 249/253/1862 250/252/1863 +f 256/258/1864 259/259/1865 258/256/1866 +f 257/257/1867 258/256/1868 252/254/1869 +f 258/256/1870 245/241/1871 241/245/1872 +f 259/259/1873 240/242/1874 245/241/1875 +f 260/4/1876 261/6/1877 255/255/1878 +f 261/6/1879 257/257/1880 249/253/1881 +f 262/260/1882 256/258/1883 257/257/1884 +f 5/263/1885 82/459/1886 452/261/1887 +f 264/265/1888 332/335/1889 331/266/1890 +f 299/304/1891 268/272/1892 267/267/1893 +f 267/267/1894 297/269/1895 299/304/1896 +f 267/267/1897 268/272/1898 270/275/1899 +f 270/275/1900 179/270/1901 267/267/1902 +f 286/274/1903 271/276/1904 270/275/1905 +f 270/275/1906 268/272/1907 286/274/1908 +f 273/277/1909 195/494/1910 179/270/1911 +f 179/270/1912 270/275/1913 273/277/1914 +f 281/279/1915 274/280/1916 273/277/1917 +f 281/279/1918 273/277/1919 271/276/1920 +f 276/281/1921 203/205/1922 195/494/1923 +f 195/494/1924 273/277/1925 276/281/1926 +f 274/280/1927 278/285/1928 277/282/1929 +f 276/281/1930 277/282/1931 207/208/1932 +f 277/282/1933 275/284/1934 4/283/1935 +f 278/285/1936 272/287/1937 275/284/1938 +f 279/278/1939 283/289/1940 282/286/1941 +f 281/279/1942 282/286/1943 278/285/1944 +f 282/286/1945 280/288/1946 272/287/1947 +f 283/289/1948 269/295/1949 280/288/1950 +f 294/291/1951 287/292/1952 286/274/1953 +f 286/274/1954 284/273/1955 294/291/1956 +f 289/293/1957 279/278/1958 271/276/1959 +f 271/276/1960 286/274/1961 289/293/1962 +f 287/292/1963 291/297/1964 290/294/1965 +f 289/293/1966 290/294/1967 283/289/1968 +f 290/294/1969 288/296/1970 269/295/1971 +f 291/297/1972 285/299/1973 288/296/1974 +f 292/290/1975 296/301/1976 295/298/1977 +f 294/291/1978 295/298/1979 291/297/1980 +f 295/298/1981 293/300/1982 285/299/1983 +f 296/301/1984 266/312/1985 293/300/1986 +f 315/303/1987 300/305/1988 299/304/1989 +f 315/303/1990 299/304/1991 297/269/1992 +f 302/306/1993 284/273/1994 268/272/1995 +f 268/272/1996 299/304/1997 302/306/1998 +f 310/308/1999 303/309/2000 302/306/2001 +f 302/306/2002 300/305/2003 310/308/2004 +f 305/310/2005 292/290/2006 284/273/2007 +f 305/310/2008 284/273/2009 302/306/2010 +f 303/309/2011 307/314/2012 306/311/2013 +f 305/310/2014 306/311/2015 296/301/2016 +f 306/311/2017 304/313/2018 266/312/2019 +f 307/314/2020 301/316/2021 304/313/2022 +f 308/307/2023 312/318/2024 311/315/2025 +f 310/308/2026 311/315/2027 307/314/2028 +f 311/315/2029 309/317/2030 301/316/2031 +f 312/318/2032 298/324/2033 309/317/2034 +f 323/320/2035 316/321/2036 315/303/2037 +f 315/303/2038 313/302/2039 323/320/2040 +f 318/322/2041 308/307/2042 300/305/2043 +f 318/322/2044 300/305/2045 315/303/2046 +f 316/321/2047 320/326/2048 319/323/2049 +f 318/322/2050 319/323/2051 312/318/2052 +f 319/323/2053 317/325/2054 298/324/2055 +f 320/326/2056 314/328/2057 317/325/2058 +f 321/319/2059 325/330/2060 324/327/2061 +f 323/320/2062 324/327/2063 320/326/2064 +f 324/327/2065 322/329/2066 314/328/2067 +f 325/330/2068 263/352/2069 322/329/2070 +f 326/332/2071 329/334/2072 328/333/2073 +f 327/331/2074 328/333/2075 219/220/2076 +f 328/333/2077 267/267/2078 85/271/2079 +f 329/334/2080 265/268/2081 267/267/2082 +f 330/264/2083 331/266/2084 222/221/2085 +f 331/266/2086 327/331/2087 216/219/2088 +f 332/335/2089 326/332/2090 327/331/2091 +f 396/338/2092 9/495/2093 13/431/2094 +f 396/338/2095 13/431/2096 427/336/2097 +f 334/341/2098 366/371/2099 368/374/2100 +f 368/374/2101 337/339/2102 334/341/2103 +f 339/344/2104 297/269/2105 265/268/2106 +f 265/268/2107 337/339/2108 339/344/2109 +f 355/343/2110 340/345/2111 339/344/2112 +f 355/343/2113 339/344/2114 337/339/2115 +f 342/346/2116 313/302/2117 297/269/2118 +f 342/346/2119 297/269/2120 339/344/2121 +f 350/348/2122 343/349/2123 342/346/2124 +f 350/348/2125 342/346/2126 340/345/2127 +f 345/350/2128 321/319/2129 313/302/2130 +f 345/350/2131 313/302/2132 342/346/2133 +f 343/349/2134 347/354/2135 346/351/2136 +f 345/350/2137 346/351/2138 325/330/2139 +f 346/351/2140 344/353/2141 263/352/2142 +f 347/354/2143 341/356/2144 344/353/2145 +f 348/347/2146 352/358/2147 351/355/2148 +f 350/348/2149 351/355/2150 347/354/2151 +f 351/355/2152 349/357/2153 341/356/2154 +f 352/358/2155 338/364/2156 349/357/2157 +f 363/360/2158 356/361/2159 355/343/2160 +f 363/360/2161 355/343/2162 353/342/2163 +f 358/362/2164 348/347/2165 340/345/2166 +f 340/345/2167 355/343/2168 358/362/2169 +f 356/361/2170 360/366/2171 359/363/2172 +f 358/362/2173 359/363/2174 352/358/2175 +f 359/363/2176 357/365/2177 338/364/2178 +f 360/366/2179 354/368/2180 357/365/2181 +f 361/359/2182 365/370/2183 364/367/2184 +f 363/360/2185 364/367/2186 360/366/2187 +f 364/367/2188 362/369/2189 354/368/2190 +f 365/370/2191 335/382/2192 362/369/2193 +f 384/373/2194 369/375/2195 368/374/2196 +f 368/374/2197 366/371/2198 384/373/2199 +f 371/376/2200 353/342/2201 337/339/2202 +f 337/339/2203 368/374/2204 371/376/2205 +f 379/378/2206 372/379/2207 371/376/2208 +f 379/378/2209 371/376/2210 369/375/2211 +f 374/380/2212 361/359/2213 353/342/2214 +f 353/342/2215 371/376/2216 374/380/2217 +f 372/379/2218 376/384/2219 375/381/2220 +f 374/380/2221 375/381/2222 365/370/2223 +f 375/381/2224 373/383/2225 335/382/2226 +f 376/384/2227 370/386/2228 373/383/2229 +f 377/377/2230 381/388/2231 380/385/2232 +f 379/378/2233 380/385/2234 376/384/2235 +f 380/385/2236 378/387/2237 370/386/2238 +f 381/388/2239 367/394/2240 378/387/2241 +f 392/390/2242 385/391/2243 384/373/2244 +f 384/373/2245 382/372/2246 392/390/2247 +f 387/392/2248 377/377/2249 369/375/2250 +f 369/375/2251 384/373/2252 387/392/2253 +f 385/391/2254 389/396/2255 388/393/2256 +f 387/392/2257 388/393/2258 381/388/2259 +f 388/393/2260 386/395/2261 367/394/2262 +f 389/396/2263 383/398/2264 386/395/2265 +f 390/389/2266 394/400/2267 393/397/2268 +f 392/390/2269 393/397/2270 389/396/2271 +f 393/397/2272 391/399/2273 383/398/2274 +f 394/400/2275 333/411/2276 391/399/2277 +f 396/338/2278 397/337/2279 399/403/2280 +f 399/403/2281 366/371/2282 396/338/2283 +f 415/402/2284 400/404/2285 399/403/2286 +f 415/402/2287 399/403/2288 397/337/2289 +f 402/405/2290 382/372/2291 366/371/2292 +f 366/371/2293 399/403/2294 402/405/2295 +f 410/407/2296 403/408/2297 402/405/2298 +f 402/405/2299 400/404/2300 410/407/2301 +f 405/409/2302 390/389/2303 382/372/2304 +f 405/409/2305 382/372/2306 402/405/2307 +f 403/408/2308 407/413/2309 406/410/2310 +f 405/409/2311 406/410/2312 394/400/2313 +f 406/410/2314 404/412/2315 333/411/2316 +f 407/413/2317 401/415/2318 404/412/2319 +f 408/406/2320 412/417/2321 411/414/2322 +f 410/407/2323 411/414/2324 407/413/2325 +f 411/414/2326 409/416/2327 401/415/2328 +f 412/417/2329 398/423/2330 409/416/2331 +f 423/419/2332 416/420/2333 415/402/2334 +f 415/402/2335 413/401/2336 423/419/2337 +f 418/421/2338 408/406/2339 400/404/2340 +f 418/421/2341 400/404/2342 415/402/2343 +f 416/420/2344 420/425/2345 419/422/2346 +f 418/421/2347 419/422/2348 412/417/2349 +f 419/422/2350 417/424/2351 398/423/2352 +f 420/425/2353 414/427/2354 417/424/2355 +f 421/418/2356 425/429/2357 424/426/2358 +f 423/419/2359 424/426/2360 420/425/2361 +f 424/426/2362 422/428/2363 414/427/2364 +f 425/429/2365 395/438/2366 422/428/2367 +f 13/431/2368 17/496/2369 428/430/2370 +f 430/432/2371 413/401/2372 397/337/2373 +f 430/432/2374 397/337/2375 427/336/2376 +f 438/434/2377 431/435/2378 430/432/2379 +f 438/434/2380 430/432/2381 428/430/2382 +f 433/436/2383 421/418/2384 413/401/2385 +f 433/436/2386 413/401/2387 430/432/2388 +f 431/435/2389 435/440/2390 434/437/2391 +f 433/436/2392 434/437/2393 425/429/2394 +f 434/437/2395 432/439/2396 395/438/2397 +f 435/440/2398 429/442/2399 432/439/2400 +f 436/433/2401 440/444/2402 439/441/2403 +f 438/434/2404 439/441/2405 435/440/2406 +f 439/441/2407 437/443/2408 429/442/2409 +f 440/444/2410 426/446/2411 437/443/2412 +f 428/430/2413 17/496/2414 21/497/2415 +f 436/433/2416 428/430/2417 1/445/2418 +f 440/444/2419 436/433/2420 1/445/2421 +f 25/498/2422 1/445/2423 428/430/2424 +f 428/430/2425 21/497/2426 25/498/2427 +f 441/448/2428 448/454/2429 447/449/2430 +f 442/452/2431 445/453/2432 444/450/2433 +f 443/451/2434 444/450/2435 329/334/2436 +f 444/450/2437 336/340/2438 265/268/2439 +f 445/453/2440 334/341/2441 336/340/2442 +f 446/447/2443 447/449/2444 332/335/2445 +f 447/449/2446 443/451/2447 326/332/2448 +f 448/454/2449 442/452/2450 443/451/2451 +f 75/457/2452 78/458/2453 450/455/2454 +f 449/456/2455 450/455/2456 445/453/2457 +f 450/455/2458 396/338/2459 334/341/2460 +f 78/458/2461 9/495/2462 396/338/2463 +f 451/262/2464 452/261/2465 448/454/2466 +f 452/261/2467 449/456/2468 442/452/2469 +f 82/459/2470 75/457/2471 449/456/2472 +f 453/461/2473 464/471/2474 463/462/2475 +f 454/465/2476 457/466/2477 456/463/2478 +f 455/464/2479 456/463/2480 247/247/2481 +f 456/463/2482 330/264/2483 6/8/2484 +f 457/466/2485 264/265/2486 330/264/2487 +f 458/469/2488 461/470/2489 460/467/2490 +f 459/468/2491 460/467/2492 259/259/2493 +f 460/467/2494 455/464/2495 240/242/2496 +f 461/470/2497 454/465/2498 455/464/2499 +f 462/460/2500 463/462/2501 262/260/2502 +f 463/462/2503 459/468/2504 256/258/2505 +f 464/471/2506 458/469/2507 459/468/2508 +f 224/474/2509 227/479/2510 470/472/2511 +f 465/477/2512 468/478/2513 467/475/2514 +f 466/476/2515 467/475/2516 457/466/2517 +f 467/475/2518 446/447/2519 264/265/2520 +f 468/478/2521 441/448/2522 446/447/2523 +f 469/473/2524 470/472/2525 468/478/2526 +f 470/472/2527 451/262/2528 441/448/2529 +f 227/479/2530 5/263/2531 451/262/2532 +f 471/481/2533 478/487/2534 477/482/2535 +f 472/485/2536 475/486/2537 474/483/2538 +f 473/484/2539 474/483/2540 461/470/2541 +f 474/483/2542 466/476/2543 454/465/2544 +f 475/486/2545 465/477/2546 466/476/2547 +f 476/480/2548 477/482/2549 464/471/2550 +f 477/482/2551 473/484/2552 458/469/2553 +f 478/487/2554 472/485/2555 473/484/2556 +f 230/490/2557 233/491/2558 480/488/2559 +f 479/489/2560 480/488/2561 475/486/2562 +f 480/488/2563 469/473/2564 465/477/2565 +f 233/491/2566 224/474/2567 469/473/2568 +f 481/1/2569 482/3/2570 478/487/2571 +f 482/3/2572 479/489/2573 472/485/2574 +f 237/492/2575 230/490/2576 479/489/2577 diff --git a/lamp.mtl b/lamp.mtl new file mode 100644 index 0000000..c89145d --- /dev/null +++ b/lamp.mtl @@ -0,0 +1,6 @@ +newmtl initialShadingGroup +illum 4 +Kd 0.50 0.50 0.50 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +Ni 1.00 diff --git a/lamp.obj b/lamp.obj new file mode 100644 index 0000000..4d0a85c --- /dev/null +++ b/lamp.obj @@ -0,0 +1,1211 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib lamp.mtl +g default +v 2.656471 15.855046 5.780191 +v 2.535695 15.855046 5.017639 +v 2.656471 15.855046 4.255087 +v 3.006978 15.855046 3.567179 +v 3.552904 15.855046 3.021253 +v 4.240812 15.855046 2.670746 +v 5.003365 15.855046 2.549970 +v 5.765916 15.855046 2.670746 +v 6.453824 15.855046 3.021253 +v 6.999750 15.855046 3.567179 +v 7.350257 15.855046 4.255087 +v 7.471033 15.855046 5.017639 +v 7.350257 15.855046 5.780191 +v 6.999750 15.855046 6.468100 +v 6.453824 15.855046 7.014026 +v 5.765916 15.855046 7.364532 +v 5.003365 15.855046 7.485309 +v 4.240812 15.855046 7.364532 +v 3.552904 15.855046 7.014026 +v 3.006978 15.855046 6.468100 +v 3.327012 19.818167 5.562319 +v 3.240743 19.818167 5.017639 +v 3.327012 19.818167 4.472960 +v 3.577374 19.818167 3.981596 +v 3.967321 19.818167 3.591650 +v 4.458684 19.818167 3.341287 +v 5.003365 19.818167 3.255018 +v 5.548044 19.818167 3.341287 +v 6.039407 19.818167 3.591650 +v 6.429354 19.818167 3.981596 +v 6.679716 19.818167 4.472960 +v 6.765985 19.818167 5.017639 +v 6.679716 19.818167 5.562319 +v 6.429354 19.818167 6.053682 +v 6.039407 19.818167 6.443629 +v 5.548044 19.818167 6.693992 +v 5.003365 19.818167 6.780261 +v 4.458684 19.818167 6.693992 +v 3.967321 19.818167 6.443629 +v 3.577374 19.818167 6.053682 +v 5.003365 19.818167 5.017639 +v 5.003365 15.855044 5.017639 +v 1.159431 0.014822 6.247877 +v 0.961787 0.014822 5.000000 +v 1.159431 0.014822 3.752123 +v 1.733017 0.014822 2.626398 +v 2.626398 0.014822 1.733017 +v 3.752123 0.014822 1.159431 +v 5.000000 0.014822 0.961787 +v 6.247877 0.014822 1.159431 +v 7.373602 0.014822 1.733017 +v 8.266983 0.014822 2.626398 +v 8.840569 0.014822 3.752123 +v 9.038213 0.014822 5.000000 +v 8.840569 0.014822 6.247877 +v 8.266983 0.014822 7.373602 +v 7.373602 0.014822 8.266983 +v 6.247877 0.014822 8.840569 +v 5.000000 0.014822 9.038213 +v 3.752123 0.014822 8.840569 +v 2.626398 0.014822 8.266983 +v 1.733017 0.014822 7.373602 +v 3.736371 -5.387635 5.410578 +v 3.671342 -5.387635 5.000000 +v 3.736371 -5.387635 4.589422 +v 3.925093 -5.387635 4.219035 +v 4.219035 -5.387635 3.925093 +v 4.589422 -5.387635 3.736371 +v 5.000000 -5.387635 3.671342 +v 5.410578 -5.387635 3.736371 +v 5.780965 -5.387635 3.925093 +v 6.074907 -5.387635 4.219035 +v 6.263629 -5.387635 4.589422 +v 6.328658 -5.387635 5.000000 +v 6.263629 -5.387635 5.410578 +v 6.074907 -5.387635 5.780965 +v 5.780965 -5.387635 6.074907 +v 5.410578 -5.387635 6.263629 +v 5.000000 -5.387635 6.328658 +v 4.589422 -5.387635 6.263629 +v 4.219035 -5.387635 6.074907 +v 3.925093 -5.387635 5.780965 +v 3.780450 -5.669678 5.396256 +v 3.717689 -5.669678 5.000000 +v 3.780450 -5.669678 4.603744 +v 3.962589 -5.669678 4.246277 +v 4.246277 -5.669678 3.962589 +v 4.603744 -5.669678 3.780450 +v 5.000000 -5.669678 3.717689 +v 5.396256 -5.669678 3.780450 +v 5.753723 -5.669678 3.962589 +v 6.037411 -5.669678 4.246277 +v 6.219550 -5.669678 4.603744 +v 6.282311 -5.669678 5.000000 +v 6.219550 -5.669678 5.396256 +v 6.037411 -5.669678 5.753723 +v 5.753723 -5.669678 6.037411 +v 5.396256 -5.669678 6.219550 +v 5.000000 -5.669678 6.282311 +v 4.603744 -5.669678 6.219550 +v 4.246277 -5.669678 6.037411 +v 3.962589 -5.669678 5.753723 +v 1.125356 -11.094143 6.258948 +v 0.925958 -11.094143 5.000000 +v 1.125356 -11.094143 3.741052 +v 1.704031 -11.094143 2.605338 +v 2.605338 -11.094143 1.704031 +v 3.741052 -11.094143 1.125356 +v 5.000000 -11.094143 0.925958 +v 6.258948 -11.094143 1.125356 +v 7.394662 -11.094143 1.704031 +v 8.295969 -11.094143 2.605338 +v 8.874644 -11.094143 3.741052 +v 9.074041 -11.094143 5.000000 +v 8.874644 -11.094143 6.258948 +v 8.295969 -11.094143 7.394662 +v 7.394662 -11.094143 8.295969 +v 6.258948 -11.094143 8.874644 +v 5.000000 -11.094143 9.074041 +v 3.741052 -11.094143 8.874644 +v 2.605338 -11.094143 8.295969 +v 1.704031 -11.094143 7.394662 +v 5.000000 0.014822 5.000000 +v 5.000000 -11.094146 5.000000 +vt 0.000000 -1.000000 +vt 1.000000 -1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 2.000000 +vt 0.000000 2.000000 +vt 1.000000 3.000000 +vt 0.000000 3.000000 +vt 1.000000 4.000000 +vt 0.000000 4.000000 +vt 1.000000 5.000000 +vt 0.000000 5.000000 +vt 1.000000 6.000000 +vt 0.000000 6.000000 +vt 1.000000 7.000000 +vt 0.000000 7.000000 +vt 1.000000 8.000000 +vt 0.000000 8.000000 +vt 1.000000 9.000000 +vt 0.000000 9.000000 +vt 1.000000 10.000000 +vt 0.000000 10.000000 +vt 1.000000 11.000000 +vt 0.000000 11.000000 +vt 1.000000 12.000000 +vt 0.000000 12.000000 +vt 1.000000 13.000000 +vt 0.000000 13.000000 +vt 1.000000 14.000000 +vt 0.000000 14.000000 +vt 1.000000 15.000000 +vt 0.000000 15.000000 +vt 1.000000 16.000000 +vt 0.000000 16.000000 +vt 1.000000 17.000000 +vt 0.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 -1.000000 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.333333 -1.000000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.000000 2.000000 +vt 0.333333 2.000000 +vt 0.000000 3.000000 +vt 0.333333 3.000000 +vt 0.000000 4.000000 +vt 0.333333 4.000000 +vt 0.000000 5.000000 +vt 0.333333 5.000000 +vt 0.000000 6.000000 +vt 0.333333 6.000000 +vt 0.000000 7.000000 +vt 0.333333 7.000000 +vt 0.000000 8.000000 +vt 0.333333 8.000000 +vt 0.000000 9.000000 +vt 0.333333 9.000000 +vt 0.000000 10.000000 +vt 0.333333 10.000000 +vt 0.000000 11.000000 +vt 0.333333 11.000000 +vt 0.000000 12.000000 +vt 0.333333 12.000000 +vt 0.000000 13.000000 +vt 0.333333 13.000000 +vt 0.000000 14.000000 +vt 0.333333 14.000000 +vt 0.000000 15.000000 +vt 0.333333 15.000000 +vt 0.000000 16.000000 +vt 0.333333 16.000000 +vt 0.000000 17.000000 +vt 0.333333 17.000000 +vt 0.000000 18.000000 +vt 0.333333 18.000000 +vt 0.666667 0.000000 +vt 0.666667 -1.000000 +vt 0.666667 1.000000 +vt 0.666667 2.000000 +vt 0.666667 3.000000 +vt 0.666667 4.000000 +vt 0.666667 5.000000 +vt 0.666667 6.000000 +vt 0.666667 7.000000 +vt 0.666667 8.000000 +vt 0.666667 9.000000 +vt 0.666667 10.000000 +vt 0.666667 11.000000 +vt 0.666667 12.000000 +vt 0.666667 13.000000 +vt 0.666667 14.000000 +vt 0.666667 15.000000 +vt 0.666667 16.000000 +vt 0.666667 17.000000 +vt 0.666667 18.000000 +vt 1.000000 0.000000 +vt 1.000000 -1.000000 +vt 1.000000 1.000000 +vt 1.000000 2.000000 +vt 1.000000 3.000000 +vt 1.000000 4.000000 +vt 1.000000 5.000000 +vt 1.000000 6.000000 +vt 1.000000 7.000000 +vt 1.000000 8.000000 +vt 1.000000 9.000000 +vt 1.000000 10.000000 +vt 1.000000 11.000000 +vt 1.000000 12.000000 +vt 1.000000 13.000000 +vt 1.000000 14.000000 +vt 1.000000 15.000000 +vt 1.000000 16.000000 +vt 1.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.984541 0.175152 0.000000 +vn -0.984541 0.175152 0.000000 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.936355 0.175152 0.304240 +vn -0.936355 0.175152 0.304240 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.850126 -0.448316 0.276223 +vn -0.893876 -0.448315 0.000000 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 0.277092 +vn -0.893876 -0.448315 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.852801 -0.442663 -0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.723160 -0.448316 -0.525407 +vn -0.725436 -0.442663 -0.527060 +vn -0.852801 -0.442663 -0.277092 +vn -0.723160 -0.448316 -0.525407 +vn -0.525407 -0.448316 -0.723160 +vn -0.527060 -0.442663 -0.725436 +vn -0.725436 -0.442663 -0.527060 +vn -0.525407 -0.448316 -0.723160 +vn -0.276223 -0.448316 -0.850126 +vn -0.277092 -0.442663 -0.852801 +vn -0.527060 -0.442663 -0.725436 +vn -0.276223 -0.448316 -0.850126 +vn 0.000000 -0.448316 -0.893875 +vn 0.000000 -0.442663 -0.896688 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.448316 -0.893875 +vn 0.276223 -0.448316 -0.850126 +vn 0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.276223 -0.448316 -0.850126 +vn 0.525407 -0.448316 -0.723160 +vn 0.527060 -0.442663 -0.725436 +vn 0.277092 -0.442663 -0.852801 +vn 0.525407 -0.448316 -0.723160 +vn 0.723160 -0.448316 -0.525407 +vn 0.725436 -0.442663 -0.527060 +vn 0.527060 -0.442663 -0.725436 +vn 0.723160 -0.448316 -0.525407 +vn 0.850126 -0.448316 -0.276223 +vn 0.852801 -0.442663 -0.277092 +vn 0.725436 -0.442663 -0.527060 +vn 0.850126 -0.448316 -0.276223 +vn 0.893876 -0.448315 0.000000 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 -0.277092 +vn 0.893876 -0.448315 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.852801 -0.442663 0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.723160 -0.448316 0.525407 +vn 0.725436 -0.442663 0.527060 +vn 0.852801 -0.442663 0.277092 +vn 0.723160 -0.448316 0.525407 +vn 0.525407 -0.448316 0.723160 +vn 0.527060 -0.442663 0.725436 +vn 0.725436 -0.442663 0.527060 +vn 0.525407 -0.448316 0.723160 +vn 0.276223 -0.448316 0.850126 +vn 0.277092 -0.442663 0.852801 +vn 0.527060 -0.442663 0.725436 +vn 0.276223 -0.448316 0.850126 +vn 0.000000 -0.448316 0.893875 +vn 0.000000 -0.442663 0.896688 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.448316 0.893875 +vn -0.276223 -0.448316 0.850126 +vn -0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn -0.276223 -0.448316 0.850126 +vn -0.525407 -0.448316 0.723160 +vn -0.527060 -0.442663 0.725436 +vn -0.277092 -0.442663 0.852801 +vn -0.525407 -0.448316 0.723160 +vn -0.723160 -0.448316 0.525407 +vn -0.725436 -0.442663 0.527060 +vn -0.527060 -0.442663 0.725436 +vn -0.723160 -0.448316 0.525407 +vn -0.850126 -0.448316 0.276223 +vn -0.852801 -0.442663 0.277092 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 0.276577 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.851218 0.446020 -0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.725436 -0.442663 -0.527060 +vn -0.724089 0.446020 -0.526081 +vn -0.851218 0.446020 -0.276577 +vn -0.725436 -0.442663 -0.527060 +vn -0.527060 -0.442663 -0.725436 +vn -0.526081 0.446020 -0.724089 +vn -0.724089 0.446020 -0.526081 +vn -0.527060 -0.442663 -0.725436 +vn -0.277092 -0.442663 -0.852801 +vn -0.276577 0.446020 -0.851218 +vn -0.526081 0.446020 -0.724089 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.000000 0.446020 -0.895023 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 -0.442663 -0.896688 +vn 0.277092 -0.442663 -0.852801 +vn 0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.277092 -0.442663 -0.852801 +vn 0.527060 -0.442663 -0.725436 +vn 0.526081 0.446020 -0.724089 +vn 0.276577 0.446020 -0.851218 +vn 0.527060 -0.442663 -0.725436 +vn 0.725436 -0.442663 -0.527060 +vn 0.724089 0.446020 -0.526081 +vn 0.526081 0.446020 -0.724089 +vn 0.725436 -0.442663 -0.527060 +vn 0.852801 -0.442663 -0.277092 +vn 0.851218 0.446020 -0.276577 +vn 0.724089 0.446020 -0.526081 +vn 0.852801 -0.442663 -0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 -0.276577 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.851218 0.446020 0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.725436 -0.442663 0.527060 +vn 0.724089 0.446020 0.526081 +vn 0.851218 0.446020 0.276577 +vn 0.725436 -0.442663 0.527060 +vn 0.527060 -0.442663 0.725436 +vn 0.526081 0.446020 0.724089 +vn 0.724089 0.446020 0.526081 +vn 0.527060 -0.442663 0.725436 +vn 0.277092 -0.442663 0.852801 +vn 0.276577 0.446020 0.851218 +vn 0.526081 0.446020 0.724089 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn 0.000000 0.446020 0.895023 +vn 0.276577 0.446020 0.851218 +vn 0.000000 -0.442663 0.896688 +vn -0.277092 -0.442663 0.852801 +vn -0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn -0.277092 -0.442663 0.852801 +vn -0.527060 -0.442663 0.725436 +vn -0.526081 0.446020 0.724089 +vn -0.276577 0.446020 0.851218 +vn -0.527060 -0.442663 0.725436 +vn -0.725436 -0.442663 0.527060 +vn -0.724089 0.446020 0.526081 +vn -0.526081 0.446020 0.724089 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.851218 0.446020 0.276577 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.889154 0.457608 0.000000 +vn -0.845636 0.457608 0.274764 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.845636 0.457608 -0.274764 +vn -0.889154 0.457608 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.724089 0.446020 -0.526081 +vn -0.719341 0.457608 -0.522631 +vn -0.845636 0.457608 -0.274764 +vn -0.724089 0.446020 -0.526081 +vn -0.526081 0.446020 -0.724089 +vn -0.522632 0.457608 -0.719341 +vn -0.719341 0.457608 -0.522631 +vn -0.526081 0.446020 -0.724089 +vn -0.276577 0.446020 -0.851218 +vn -0.274764 0.457608 -0.845636 +vn -0.522632 0.457608 -0.719341 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.000000 0.457608 -0.889154 +vn -0.274764 0.457608 -0.845636 +vn 0.000000 0.446020 -0.895023 +vn 0.276577 0.446020 -0.851218 +vn 0.274764 0.457608 -0.845636 +vn 0.000000 0.457608 -0.889154 +vn 0.276577 0.446020 -0.851218 +vn 0.526081 0.446020 -0.724089 +vn 0.522632 0.457608 -0.719341 +vn 0.274764 0.457608 -0.845636 +vn 0.526081 0.446020 -0.724089 +vn 0.724089 0.446020 -0.526081 +vn 0.719341 0.457608 -0.522631 +vn 0.522632 0.457608 -0.719341 +vn 0.724089 0.446020 -0.526081 +vn 0.851218 0.446020 -0.276577 +vn 0.845636 0.457608 -0.274764 +vn 0.719341 0.457608 -0.522631 +vn 0.851218 0.446020 -0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.889154 0.457608 0.000000 +vn 0.845636 0.457608 -0.274764 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.845636 0.457608 0.274764 +vn 0.889154 0.457608 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.724089 0.446020 0.526081 +vn 0.719341 0.457608 0.522631 +vn 0.845636 0.457608 0.274764 +vn 0.724089 0.446020 0.526081 +vn 0.526081 0.446020 0.724089 +vn 0.522632 0.457608 0.719341 +vn 0.719341 0.457608 0.522631 +vn 0.526081 0.446020 0.724089 +vn 0.276577 0.446020 0.851218 +vn 0.274764 0.457608 0.845636 +vn 0.522632 0.457608 0.719341 +vn 0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn 0.000000 0.457608 0.889154 +vn 0.274764 0.457608 0.845636 +vn 0.000000 0.446020 0.895023 +vn -0.276577 0.446020 0.851218 +vn -0.274764 0.457608 0.845636 +vn 0.000000 0.457608 0.889154 +vn -0.276577 0.446020 0.851218 +vn -0.526081 0.446020 0.724089 +vn -0.522632 0.457608 0.719341 +vn -0.274764 0.457608 0.845636 +vn -0.526081 0.446020 0.724089 +vn -0.724089 0.446020 0.526081 +vn -0.719341 0.457608 0.522631 +vn -0.522632 0.457608 0.719341 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.845636 0.457608 0.274764 +vn -0.719341 0.457608 0.522631 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +s off +g polySurface1 +usemtl initialShadingGroup +f 1/1/1 21/2/2 22/3/3 2/4/4 +f 2/4/5 22/3/6 23/5/7 3/6/8 +f 3/6/9 23/5/10 24/7/11 4/8/12 +f 4/8/13 24/7/14 25/9/15 5/10/16 +f 5/10/17 25/9/18 26/11/19 6/12/20 +f 6/12/21 26/11/22 27/13/23 7/14/24 +f 7/14/25 27/13/26 28/15/27 8/16/28 +f 8/16/29 28/15/30 29/17/31 9/18/32 +f 9/18/33 29/17/34 30/19/35 10/20/36 +f 10/20/37 30/19/38 31/21/39 11/22/40 +f 11/22/41 31/21/42 32/23/43 12/24/44 +f 12/24/45 32/23/46 33/25/47 13/26/48 +f 13/26/49 33/25/50 34/27/51 14/28/52 +f 14/28/53 34/27/54 35/29/55 15/30/56 +f 15/30/57 35/29/58 36/31/59 16/32/60 +f 16/32/61 36/31/62 37/33/63 17/34/64 +f 17/34/65 37/33/66 38/35/67 18/36/68 +f 18/36/69 38/35/70 39/37/71 19/38/72 +f 19/38/73 39/37/74 40/39/75 20/40/76 +f 20/40/77 40/39/78 21/2/79 1/1/80 +f 22/41/81 21/42/82 41/43/83 +f 23/44/84 22/45/85 41/46/86 +f 24/47/87 23/48/88 41/49/89 +f 25/50/90 24/51/91 41/52/92 +f 26/53/93 25/54/94 41/55/95 +f 27/56/96 26/57/97 41/58/98 +f 28/59/99 27/60/100 41/61/101 +f 29/62/102 28/63/103 41/64/104 +f 30/65/105 29/66/106 41/67/107 +f 31/68/108 30/69/109 41/70/110 +f 32/71/111 31/72/112 41/73/113 +f 33/74/114 32/75/115 41/76/116 +f 34/77/117 33/78/118 41/79/119 +f 35/80/120 34/81/121 41/82/122 +f 36/83/123 35/84/124 41/85/125 +f 37/86/126 36/87/127 41/88/128 +f 38/89/129 37/90/130 41/91/131 +f 39/92/132 38/93/133 41/94/134 +f 40/95/135 39/96/136 41/97/137 +f 21/98/138 40/99/139 41/100/140 +f 1/101/141 2/102/142 42/103/143 +f 2/104/144 3/105/145 42/106/146 +f 3/107/147 4/108/148 42/109/149 +f 4/110/150 5/111/151 42/112/152 +f 5/113/153 6/114/154 42/115/155 +f 6/116/156 7/117/157 42/118/158 +f 7/119/159 8/120/160 42/121/161 +f 8/122/162 9/123/163 42/124/164 +f 9/125/165 10/126/166 42/127/167 +f 10/128/168 11/129/169 42/130/170 +f 11/131/171 12/132/172 42/133/173 +f 12/134/174 13/135/175 42/136/176 +f 13/137/177 14/138/178 42/139/179 +f 14/140/180 15/141/181 42/142/182 +f 15/143/183 16/144/184 42/145/185 +f 16/146/186 17/147/187 42/148/188 +f 17/149/189 18/150/190 42/151/191 +f 18/152/192 19/153/193 42/154/194 +f 19/155/195 20/156/196 42/157/197 +f 20/158/198 1/159/199 42/160/200 +f 43/161/201 44/162/202 64/163/203 63/164/204 +f 44/162/205 45/165/206 65/166/207 64/163/208 +f 45/165/209 46/167/210 66/168/211 65/166/212 +f 46/167/213 47/169/214 67/170/215 66/168/216 +f 47/169/217 48/171/218 68/172/219 67/170/220 +f 48/171/221 49/173/222 69/174/223 68/172/224 +f 49/173/225 50/175/226 70/176/227 69/174/228 +f 50/175/229 51/177/230 71/178/231 70/176/232 +f 51/177/233 52/179/234 72/180/235 71/178/236 +f 52/179/237 53/181/238 73/182/239 72/180/240 +f 53/181/241 54/183/242 74/184/243 73/182/244 +f 54/183/245 55/185/246 75/186/247 74/184/248 +f 55/185/249 56/187/250 76/188/251 75/186/252 +f 56/187/253 57/189/254 77/190/255 76/188/256 +f 57/189/257 58/191/258 78/192/259 77/190/260 +f 58/191/261 59/193/262 79/194/263 78/192/264 +f 59/193/265 60/195/266 80/196/267 79/194/268 +f 60/195/269 61/197/270 81/198/271 80/196/272 +f 61/197/273 62/199/274 82/200/275 81/198/276 +f 62/199/277 43/161/278 63/164/279 82/200/280 +f 63/164/281 64/163/282 84/201/283 83/202/284 +f 64/163/285 65/166/286 85/203/287 84/201/288 +f 65/166/289 66/168/290 86/204/291 85/203/292 +f 66/168/293 67/170/294 87/205/295 86/204/296 +f 67/170/297 68/172/298 88/206/299 87/205/300 +f 68/172/301 69/174/302 89/207/303 88/206/304 +f 69/174/305 70/176/306 90/208/307 89/207/308 +f 70/176/309 71/178/310 91/209/311 90/208/312 +f 71/178/313 72/180/314 92/210/315 91/209/316 +f 72/180/317 73/182/318 93/211/319 92/210/320 +f 73/182/321 74/184/322 94/212/323 93/211/324 +f 74/184/325 75/186/326 95/213/327 94/212/328 +f 75/186/329 76/188/330 96/214/331 95/213/332 +f 76/188/333 77/190/334 97/215/335 96/214/336 +f 77/190/337 78/192/338 98/216/339 97/215/340 +f 78/192/341 79/194/342 99/217/343 98/216/344 +f 79/194/345 80/196/346 100/218/347 99/217/348 +f 80/196/349 81/198/350 101/219/351 100/218/352 +f 81/198/353 82/200/354 102/220/355 101/219/356 +f 82/200/357 63/164/358 83/202/359 102/220/360 +f 83/202/361 84/201/362 104/221/363 103/222/364 +f 84/201/365 85/203/366 105/223/367 104/221/368 +f 85/203/369 86/204/370 106/224/371 105/223/372 +f 86/204/373 87/205/374 107/225/375 106/224/376 +f 87/205/377 88/206/378 108/226/379 107/225/380 +f 88/206/381 89/207/382 109/227/383 108/226/384 +f 89/207/385 90/208/386 110/228/387 109/227/388 +f 90/208/389 91/209/390 111/229/391 110/228/392 +f 91/209/393 92/210/394 112/230/395 111/229/396 +f 92/210/397 93/211/398 113/231/399 112/230/400 +f 93/211/401 94/212/402 114/232/403 113/231/404 +f 94/212/405 95/213/406 115/233/407 114/232/408 +f 95/213/409 96/214/410 116/234/411 115/233/412 +f 96/214/413 97/215/414 117/235/415 116/234/416 +f 97/215/417 98/216/418 118/236/419 117/235/420 +f 98/216/421 99/217/422 119/237/423 118/236/424 +f 99/217/425 100/218/426 120/238/427 119/237/428 +f 100/218/429 101/219/430 121/239/431 120/238/432 +f 101/219/433 102/220/434 122/240/435 121/239/436 +f 102/220/437 83/202/438 103/222/439 122/240/440 +f 44/241/441 43/242/442 123/243/443 +f 45/244/444 44/245/445 123/246/446 +f 46/247/447 45/248/448 123/249/449 +f 47/250/450 46/251/451 123/252/452 +f 48/253/453 47/254/454 123/255/455 +f 49/256/456 48/257/457 123/258/458 +f 50/259/459 49/260/460 123/261/461 +f 51/262/462 50/263/463 123/264/464 +f 52/265/465 51/266/466 123/267/467 +f 53/268/468 52/269/469 123/270/470 +f 54/271/471 53/272/472 123/273/473 +f 55/274/474 54/275/475 123/276/476 +f 56/277/477 55/278/478 123/279/479 +f 57/280/480 56/281/481 123/282/482 +f 58/283/483 57/284/484 123/285/485 +f 59/286/486 58/287/487 123/288/488 +f 60/289/489 59/290/490 123/291/491 +f 61/292/492 60/293/493 123/294/494 +f 62/295/495 61/296/496 123/297/497 +f 43/298/498 62/299/499 123/300/500 +f 103/301/501 104/302/502 124/303/503 +f 104/304/504 105/305/505 124/306/506 +f 105/307/507 106/308/508 124/309/509 +f 106/310/510 107/311/511 124/312/512 +f 107/313/513 108/314/514 124/315/515 +f 108/316/516 109/317/517 124/318/518 +f 109/319/519 110/320/520 124/321/521 +f 110/322/522 111/323/523 124/324/524 +f 111/325/525 112/326/526 124/327/527 +f 112/328/528 113/329/529 124/330/530 +f 113/331/531 114/332/532 124/333/533 +f 114/334/534 115/335/535 124/336/536 +f 115/337/537 116/338/538 124/339/539 +f 116/340/540 117/341/541 124/342/542 +f 117/343/543 118/344/544 124/345/545 +f 118/346/546 119/347/547 124/348/548 +f 119/349/549 120/350/550 124/351/551 +f 120/352/552 121/353/553 124/354/554 +f 121/355/555 122/356/556 124/357/557 +f 122/358/558 103/359/559 124/360/560 diff --git a/my-new-chrome-extension/.babelrc b/my-new-chrome-extension/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/my-new-chrome-extension/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/my-new-chrome-extension/.bowerrc b/my-new-chrome-extension/.bowerrc new file mode 100644 index 0000000..5773025 --- /dev/null +++ b/my-new-chrome-extension/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "app/bower_components" +} diff --git a/my-new-chrome-extension/.editorconfig b/my-new-chrome-extension/.editorconfig new file mode 100644 index 0000000..609f684 --- /dev/null +++ b/my-new-chrome-extension/.editorconfig @@ -0,0 +1,24 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 2 + +[*.json] +indent_size = 2 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/my-new-chrome-extension/.gitattributes b/my-new-chrome-extension/.gitattributes new file mode 100644 index 0000000..2125666 --- /dev/null +++ b/my-new-chrome-extension/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/my-new-chrome-extension/.gitignore b/my-new-chrome-extension/.gitignore new file mode 100644 index 0000000..5d65bce --- /dev/null +++ b/my-new-chrome-extension/.gitignore @@ -0,0 +1,10 @@ +node_modules +temp +.tmp +dist +.sass-cache +app/bower_components +test/bower_components +package +app/scripts + diff --git a/my-new-chrome-extension/.yo-rc.json b/my-new-chrome-extension/.yo-rc.json new file mode 100644 index 0000000..c6bb600 --- /dev/null +++ b/my-new-chrome-extension/.yo-rc.json @@ -0,0 +1,6 @@ +{ + "generator-mocha": { + "ui": "bdd", + "rjs": false + } +} \ No newline at end of file diff --git a/my-new-chrome-extension/app/_locales/en/messages.json b/my-new-chrome-extension/app/_locales/en/messages.json new file mode 100644 index 0000000..c549c8b --- /dev/null +++ b/my-new-chrome-extension/app/_locales/en/messages.json @@ -0,0 +1,10 @@ +{ + "appName": { + "message": "lavalamp", + "description": "The name of the application" + }, + "appDescription": { + "message": "My Chrome Extension", + "description": "The description of the application" + } +} diff --git a/my-new-chrome-extension/app/images/icon-128.png b/my-new-chrome-extension/app/images/icon-128.png new file mode 100644 index 0000000000000000000000000000000000000000..75c023a5375c531107c7c09fe60778d6b9df039d GIT binary patch literal 5356 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 KMNUMnLSTZKC-pl3 literal 0 HcmV?d00001 diff --git a/my-new-chrome-extension/app/images/icon-16.png b/my-new-chrome-extension/app/images/icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..7df748fba2ddbbf6c7dc55d9fac800fe42d9c062 GIT binary patch literal 758 zcmVet+KcdbD@$)%ow_#5N6ldvkl$WuOsFT#TT^F-NI2C@62baIk+#7jsHe zx+rlsi?A5mpwU%b6m$`UR8qT`t_Hi%F$QCs$+F=to_^n-((tB>59j$k&+~oYpm~cy zJ`T}VTY}d*l6+-0J_o3IW6a-<2aZ*3%wN{nU&^v4CbUC2tT9XOUH{)eY%PkdO{cWE6DsA7A0PeC$aP2H2STM0C~dShi*}=E zH;OQU;Ps|Vo7+$(Wpdx}5K;3jTzh{22`#4l6mR%6)d!b>6bs4_o7+^#L1cwCNc4(cDWsPht=M zK@0B&Iew2F{K1XfL!J-O>NDvqyY4Pkygu**)YAY4+EIMwBUEz)l^jRH0hIG7DtOYp z`<)g~vNNvJj(7sV>+8Rei3{1%_?jwB5h2#W##afOJwcVGxphlC=LfEi7x4SBo$p;4 zEAY3OH~8IH7r#BVmtVZy$R9s>RS+$n&*nbs;~a^ZCT9Y3%-nXA8jBAHznuH~b< zGvwN3^4cVCec8*0^P_@j@qD&+=X2gTSzuw3Bi$nbQ@C!Wh zQX`LbH*&PQN)Roc&lWBXk(ax<^l9s~AL!bZps%wIQ*Sn1I*_E92iRf3P6ak^O$nmK z^O`Aj;}l^Z|MR}(cHN}^wT zlN7r$0iOf7+wsAH99PGB1<~S3<~!1r8$Zxf6=n8svjbgOec|1fn#GYt<807*qoM6N<$g35_)Pyhe` literal 0 HcmV?d00001 diff --git a/my-new-chrome-extension/app/manifest.json b/my-new-chrome-extension/app/manifest.json new file mode 100644 index 0000000..e7e414d --- /dev/null +++ b/my-new-chrome-extension/app/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "__MSG_appName__", + "version": "0.0.1", + "manifest_version": 2, + "description": "__MSG_appDescription__", + "icons": { + "16": "images/icon-16.png", + "128": "images/icon-128.png" + }, + "default_locale": "en", + "background": { + "scripts": [ + "scripts/chromereload.js", + "scripts/background.js" + ] + }, + "permissions": [] +} diff --git a/my-new-chrome-extension/app/scripts.babel/background.js b/my-new-chrome-extension/app/scripts.babel/background.js new file mode 100644 index 0000000..f8635f4 --- /dev/null +++ b/my-new-chrome-extension/app/scripts.babel/background.js @@ -0,0 +1,7 @@ +'use strict'; + +chrome.runtime.onInstalled.addListener(details => { + console.log('previousVersion', details.previousVersion); +}); + +console.log('\'Allo \'Allo! Event Page'); diff --git a/my-new-chrome-extension/app/scripts.babel/chromereload.js b/my-new-chrome-extension/app/scripts.babel/chromereload.js new file mode 100644 index 0000000..cf8e6fd --- /dev/null +++ b/my-new-chrome-extension/app/scripts.babel/chromereload.js @@ -0,0 +1,23 @@ +'use strict'; + +// Reload client for Chrome Apps & Extensions. +// The reload client has a compatibility with livereload. +// WARNING: only supports reload command. + +const LIVERELOAD_HOST = 'localhost:'; +const LIVERELOAD_PORT = 35729; +const connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload'); + +connection.onerror = error => { + console.log('reload connection got error:', error); +}; + +connection.onmessage = e => { + if (e.data) { + const data = JSON.parse(e.data); + if (data && data.command === 'reload') { + chrome.runtime.reload(); + } + } +}; + diff --git a/my-new-chrome-extension/bower.json b/my-new-chrome-extension/bower.json new file mode 100644 index 0000000..b5d23f4 --- /dev/null +++ b/my-new-chrome-extension/bower.json @@ -0,0 +1,7 @@ +{ + "name": "lavalamp", + "private": true, + "version": "0.0.0", + "dependencies": {}, + "devDependencies": {} +} diff --git a/my-new-chrome-extension/gulpfile.babel.js b/my-new-chrome-extension/gulpfile.babel.js new file mode 100644 index 0000000..e11c754 --- /dev/null +++ b/my-new-chrome-extension/gulpfile.babel.js @@ -0,0 +1,135 @@ +// generated on 2017-02-26 using generator-chrome-extension 0.6.1 +import gulp from 'gulp'; +import gulpLoadPlugins from 'gulp-load-plugins'; +import del from 'del'; +import runSequence from 'run-sequence'; +import {stream as wiredep} from 'wiredep'; + +const $ = gulpLoadPlugins(); + +gulp.task('extras', () => { + return gulp.src([ + 'app/*.*', + 'app/_locales/**', + '!app/scripts.babel', + '!app/*.json', + '!app/*.html', + ], { + base: 'app', + dot: true + }).pipe(gulp.dest('dist')); +}); + +function lint(files, options) { + return () => { + return gulp.src(files) + .pipe($.eslint(options)) + .pipe($.eslint.format()); + }; +} + +gulp.task('lint', lint('app/scripts.babel/**/*.js', { + env: { + es6: true + } +})); + +gulp.task('images', () => { + return gulp.src('app/images/**/*') + .pipe($.if($.if.isFile, $.cache($.imagemin({ + progressive: true, + interlaced: true, + // don't remove IDs from SVGs, they are often used + // as hooks for embedding and styling + svgoPlugins: [{cleanupIDs: false}] + })) + .on('error', function (err) { + console.log(err); + this.end(); + }))) + .pipe(gulp.dest('dist/images')); +}); + +gulp.task('html', () => { + return gulp.src('app/*.html') + .pipe($.useref({searchPath: ['.tmp', 'app', '.']})) + .pipe($.sourcemaps.init()) + .pipe($.if('*.js', $.uglify())) + .pipe($.if('*.css', $.cleanCss({compatibility: '*'}))) + .pipe($.sourcemaps.write()) + .pipe($.if('*.html', $.htmlmin({removeComments: true, collapseWhitespace: true}))) + .pipe(gulp.dest('dist')); +}); + +gulp.task('chromeManifest', () => { + return gulp.src('app/manifest.json') + .pipe($.chromeManifest({ + buildnumber: true, + background: { + target: 'scripts/background.js', + exclude: [ + 'scripts/chromereload.js' + ] + } + })) + .pipe($.if('*.css', $.cleanCss({compatibility: '*'}))) + .pipe($.if('*.js', $.sourcemaps.init())) + .pipe($.if('*.js', $.uglify())) + .pipe($.if('*.js', $.sourcemaps.write('.'))) + .pipe(gulp.dest('dist')); +}); + +gulp.task('babel', () => { + return gulp.src('app/scripts.babel/**/*.js') + .pipe($.babel({ + presets: ['es2015'] + })) + .pipe(gulp.dest('app/scripts')); +}); + +gulp.task('clean', del.bind(null, ['.tmp', 'dist'])); + +gulp.task('watch', ['lint', 'babel'], () => { + $.livereload.listen(); + + gulp.watch([ + 'app/*.html', + 'app/scripts/**/*.js', + 'app/images/**/*', + 'app/styles/**/*', + 'app/_locales/**/*.json' + ]).on('change', $.livereload.reload); + + gulp.watch('app/scripts.babel/**/*.js', ['lint', 'babel']); + gulp.watch('bower.json', ['wiredep']); +}); + +gulp.task('size', () => { + return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true})); +}); + +gulp.task('wiredep', () => { + gulp.src('app/*.html') + .pipe(wiredep({ + ignorePath: /^(\.\.\/)*\.\./ + })) + .pipe(gulp.dest('app')); +}); + +gulp.task('package', function () { + var manifest = require('./dist/manifest.json'); + return gulp.src('dist/**') + .pipe($.zip('lavalamp-' + manifest.version + '.zip')) + .pipe(gulp.dest('package')); +}); + +gulp.task('build', (cb) => { + runSequence( + 'lint', 'babel', 'chromeManifest', + ['html', 'images', 'extras'], + 'size', cb); +}); + +gulp.task('default', ['clean'], cb => { + runSequence('build', cb); +}); diff --git a/my-new-chrome-extension/package.json b/my-new-chrome-extension/package.json new file mode 100644 index 0000000..dd0184e --- /dev/null +++ b/my-new-chrome-extension/package.json @@ -0,0 +1,47 @@ +{ + "name": "lavalamp", + "private": true, + "engines": { + "node": ">=0.8.0" + }, + "devDependencies": { + "babel-core": "^6.7.2", + "babel-preset-es2015": "^6.6.0", + "del": "^2.2.0", + "gulp": "^3.9.1", + "gulp-babel": "^6.1.2", + "gulp-cache": "^0.4.3", + "gulp-chrome-manifest": "0.0.13", + "gulp-clean-css": "^2.0.3", + "gulp-eslint": "^2.0.0", + "gulp-if": "^2.0.0", + "gulp-imagemin": "^2.4.0", + "gulp-livereload": "^3.8.1", + "gulp-load-plugins": "^1.2.0", + "gulp-htmlmin": "^1.3.0", + "gulp-size": "^2.1.0", + "gulp-sourcemaps": "^1.6.0", + "gulp-uglify": "^1.5.3", + "gulp-useref": "^3.0.8", + "gulp-zip": "^3.2.0", + "main-bower-files": "^2.11.1", + "run-sequence": "^1.1.5", + "wiredep": "^4.0.0" + }, + "eslintConfig": { + "env": { + "node": true, + "browser": true + }, + "globals": { + "chrome": true + }, + "rules": { + "eol-last": 0, + "quotes": [ + 2, + "single" + ] + } + } +} diff --git a/my-new-chrome-extension/test/index.html b/my-new-chrome-extension/test/index.html new file mode 100644 index 0000000..6498d5f --- /dev/null +++ b/my-new-chrome-extension/test/index.html @@ -0,0 +1,29 @@ + + + + + Mocha Spec Runner + + + +
+ + + + + + + + + + + + diff --git a/my-new-chrome-extension/test/spec/test.js b/my-new-chrome-extension/test/spec/test.js new file mode 100644 index 0000000..0fca0fb --- /dev/null +++ b/my-new-chrome-extension/test/spec/test.js @@ -0,0 +1,11 @@ +(function () { + 'use strict'; + + describe('Give it some context', function () { + describe('maybe a bit more context here', function () { + it('should run here few assertions', function () { + + }); + }); + }); +})(); diff --git a/quote.js b/quote.js new file mode 100644 index 0000000..55bca89 --- /dev/null +++ b/quote.js @@ -0,0 +1,45 @@ +//Function to pick a quote and corresponding author based on the random integer, then populate the quote HTML elements +function quote() { +//Array to store the list of quotes +var quoteArray = ["Success is most often achieved by those who don't know that failure is inevitable.","Things work out best for those who make the best of how things work out.","Courage is grace under pressure.","If you are not willing to risk the usual, you will have to settle for the ordinary.","Learn from yesterday, live for today, hope for tomorrow. The important thing is not to stop questioning.","Take up one idea. Make that one idea your life -- think of it, dream of it, live on that idea. Let the brain, muscles, nerves, every part of your body be full of that idea, and just leave every other idea alone. This is the way to success.","Sometimes you can't see yourself clearly until you see yourself through the eyes of others.","All our dreams can come true if we have the courage to pursue them.","It does not matter how slowly you go, so long as you do not stop.","Success is walking from failure to failure with no loss of enthusiasm.","Someone is sitting in the shade today because someone planted a tree a long time ago.","Whenever you see a successful person, you only see the public glories, never the private sacrifices to reach them.","Don't cry because it's over, smile because it happened.","Success? I don't know what that word means. I'm happy. But success, that goes back to what in somebody's eyes success means. For me, success is inner peace. That's a good day for me.","You only live once, but if you do it right, once is enough.","Opportunities don't happen. You create them.","Once you choose hope, anything's possible.","Try not to become a person of success, but rather try to become a person of value.","There is no easy walk to freedom anywhere, and many of us will have to pass through the valley of the shadow of death again and again before we reach the mountaintop of our desires.","It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change.","The best and most beautiful things in the world cannot be seen or even touched -- they must be felt with the heart.","Great minds discuss ideas; average minds discuss events; small minds discuss people.","Live as if you were to die tomorrow. Learn as if you were to live forever.","The best revenge is massive success.","The difference between winning and losing is most often not quitting.","I have not failed. I've just found 10,000 ways that won't work.","When you cease to dream you cease to live.","A successful man is one who can lay a firm foundation with the bricks others have thrown at him.","May you live every day of your life.","No one can make you feel inferior without your consent.","Failure is another steppingstone to greatness.","The whole secret of a successful life is to find out what is one's destiny to do, and then do it.","If you're not stubborn, you'll give up on experiments too soon. And if you're not flexible, you'll pound your head against the wall and you won't see a different solution to a problem you're trying to solve.","If you're going through hell, keep going.","In order to be irreplaceable one must always be different.","What seems to us as bitter trials are often blessings in disguise.","You miss 100 percent of the shots you don't take.","The distance between insanity and genius is measured only by success.","The way I see it, if you want the rainbow, you gotta put up with the rain.","To me, business isn't about wearing suits or pleasing stockholders. It's about being true to yourself, your ideas and focusing on the essentials.","The longer I live, the more beautiful life becomes.","Happiness is a butterfly, which when pursued, is always beyond your grasp, but which, if you will sit down quietly, may alight upon you.","You must expect great things of yourself before you can do them.","If you can't explain it simply, you don't understand it well enough.","You can't please everyone, and you can't make everyone like you.","There are two types of people who will tell you that you cannot make a difference in this world: those who are afraid to try and those who are afraid you will succeed.","I believe every human has a finite number of heartbeats. I don't intend to waste any of mine.","Start where you are. Use what you have. Do what you can.","Don't limit yourself. Many people limit themselves to what they think they can do. You can go as far as your mind lets you. What you believe, remember, you can achieve.","People ask, 'What's the best role you've ever played?' The next one.","The two most important days in your life are the day you are born and the day you find out why.","I find that the harder I work, the more luck I seem to have.","It often requires more courage to dare to do right than to fear to do wrong.","Success is the sum of small efforts, repeated day-in and day-out.","As you grow older, you will discover that you have two hands, one for helping yourself, the other for helping others.","If you want to achieve excellence, you can get there today. As of this second, quit doing less-than-excellent work.","If your actions inspire others to dream more, learn more, do more, and become more, you are a leader.","All progress takes place outside the comfort zone.","The more you praise and celebrate your life, the more there is in life to celebrate.","You may only succeed if you desire succeeding; you may only fail if you do not mind failing.","A dream doesn't become reality through magic; it takes sweat, determination, and hard work.","Only put off until tomorrow what you are willing to die having left undone.","The biggest risk is not taking any risk... In a world that's changing really quickly, the only strategy that is guaranteed to fail is not taking risks.","We become what we think about most of the time, and that's the strangest secret.","Do one thing every day that scares you.","The only place where success comes before work is in the dictionary.","Don't be afraid to give up the good to go for the great.","Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it.","Don't worry about failure; you only have to be right once.","Though no one can go back and make a brand-new start, anyone can start from now and make a brand-new ending.","Nothing great was ever achieved without enthusiasm.","Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore. Dream. Discover.","Keep your face to the sunshine and you can never see the shadow.","The first step toward success is taken when you refuse to be a captive of the environment in which you first find yourself.","One of the greatest diseases is to be nobody to anybody.","Identity is a prison you can never escape, but the way to redeem your past is not to run from it, but to try to understand it, and use it as a foundation to grow.","The successful warrior is the average man, with laser-like focus.","Rarely have I seen a situation where doing less than the other guy is a good strategy.","If you always do what interests you, at least one person is pleased.","Keep on going, and the chances are that you will stumble on something, perhaps when you are least expecting it. I never heard of anyone ever stumbling on something sitting down.","I avoid looking forward or backward, and try to keep looking upward.","You can't connect the dots looking forward; you can only connect them looking backward. So you have to trust that the dots will somehow connect in your future. You have to trust in something -- your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.","Life is short, and it is here to be lived.","Everything you can imagine is real.","Change will not come if we wait for some other person or some other time. We are the ones we've been waiting for. We are the change that we seek.","If you want to make a permanent change, stop focusing on the size of your problems and start focusing on the size of you!","Successful people do what unsuccessful people are not willing to do. Don't wish it were easier; wish you were better.","It is never too late to be what you might have been.","If you love what you do and are willing to do what it takes, it's within your reach. And it'll be worth every minute you spend alone at night, thinking and thinking about what it is you want to design or build.","In my experience, there is only one motivation, and that is desire. No reasons or principle contain it or stand against it.","In the midst of movement and chaos, keep stillness inside of you.","Success does not consist in never making mistakes but in never making the same one a second time.","I don't want to get to the end of my life and find that I lived just the length of it. I want to have lived the width of it as well.","As we look ahead into the next century, leaders will be those who empower others.","Our greatest fear should not be of failure... but of succeeding at things in life that don't really matter.","Be yourself. Everyone else is already taken.","If you don't design your own life plan, chances are you'll fall into someone else's plan. And guess what they have planned for you? Not much.","But you have to do what you dream of doing even while you're afraid.","To be successful, you must accept all challenges that come your way. You can't just accept the ones you like.","Be patient with yourself. Self-growth is tender; it's holy ground. There's no greater investment.","Many of life's failures are people who did not realize how close they were to success when they gave up.","If you can copy and paste one hundred and one inspirational quotes, you can do anything"] +//Array to store the corresponding quote authors +var authorArray = ["Coco Chanel","John Wooden","Ernest Hemingway","Jim Rohn","Albert Einstein","Swami Vivekananda","Ellen DeGeneres","Walt Disney","Confucius","Winston Churchill","Warren Buffett","Vaibhav Shah","Dr. Seuss","Denzel Washington","Mae West","Chris Grosser","Christopher Reeve","Albert Einstein","Nelson Mandela","Charles Darwin","Helen Keller","Eleanor Roosevelt","Mahatma Gandhi","Frank Sinatra","Walt Disney","Thomas Edison","Malcolm Forbes","David Brinkley","Jonathan Swift","Eleanor Roosevelt","Oprah Winfrey","Henry Ford","Jeff Bezos","Winston Churchill","Coco Chanel","Oscar Wilde","Wayne Gretzky","Bruce Feirstein","Dolly Parton","Richard Branson","Frank Lloyd Wright","Nathaniel Hawthorne","Michael Jordan","Albert Einstein","Katie Couric","Ray Goforth","Neil Armstrong","Arthur Ashe","Mary Kay Ash","Kevin Kline","Mark Twain","Thomas Jefferson","Abraham Lincoln","Robert Collier","Audrey Hepburn","Thomas J. Watson","John Quincy Adams","Michael John Bobak","Oprah Winfrey","Philippos","Colin Powell","Pablo Picasso","Mark Zuckerberg","Earl Nightingale","Eleanor Roosevelt","Vidal Sassoon","John D. Rockefeller","Steve Jobs","Drew Houston","Carl Bard","Ralph Waldo Emerson","Mark Twain","Helen Keller","Mark Caine","Mother Teresa","Jay-Z","Bruce Lee","Jimmy Spithill","Katharine Hepburn","Charles F. Kettering","Charlotte Bronte","Steve Jobs","Kate Winslet","Picasso","Barack Obama","T. Harv Eker","Jim Rohn","George Eliot","Steve Wozniak","Jane Smiley","Deepak Chopra","George Bernard Shaw","Diane Ackerman","Bill Gates","Francis Chan","Oscar Wilde","Jim Rohn","Arianna Huffington","Mike Gafka","Stephen Covey","Thomas A. Edison","Daniel Cole"] +//Call the randomNumber function to obtain a random number. Send the number of quotes as the upper limit. Store returned integer in the quoteNumber variable +var quoteNumber = randomNumber(quoteArray.length,currentNumber) +//Use the quote number to pick the quote text and corresponding author. Store in the quoteBody and quoteAuthor variables +var quoteBody = quoteArray[quoteNumber] +var quoteAuthor = authorArray[quoteNumber] +//Update the currentNumber global variable +currentNumber = quoteNumber +//Populate the quoteBody and quoteAuthor HTML elements with the chosen quote text and author +document.getElementById("quoteBodyDesktop").innerHTML = '"' + quoteBody + '"' +document.getElementById("quoteAuthorDesktop").innerHTML = quoteAuthor +//document.getElementById("quoteBodyMobile").innerHTML = '"' + quoteBody + '"' +//document.getElementById("quoteAuthorMobile").innerHTML = quoteAuthor +//Create seperate variables with the quote body and quote text encoded for adding to tweet intent URL +var quoteBodyURI = encodeURIComponent(quoteBody) +var quoteAuthorURI = encodeURIComponent(quoteAuthor) +//Amend the href attribute for the share button accordingly +//document.getElementById("buttonTweet").href = 'https://twitter.com/intent/tweet?text=' + '"' + quoteBodyURI + '"' + ' - ' + quoteAuthorURI +} + +//Function to generate a random integer using the total number of quotes in the array as the upper limit +function randomNumber(numQuotes,previousNumber) { +//First generate the random number +var number = Math.floor(Math.random() * numQuotes) +//Check if this is the first run of the generator i.e. page loading +if (previousNumber === null) { +return number; +} +//If this isn't the first run of the generator i.e. button click, check the new number is not the same as the last. If it is, loop the randomiser until it isn't, then return the random number +while (number === previousNumber) { + number = Math.floor(Math.random() * numQuotes) +} +return number +} + +//Set previous random number to null, as there is no previous number on page load +var currentNumber = null; + +//Call the quote function on page load to populate with a quote +window.onload = quote; \ No newline at end of file diff --git a/src/assets/caspern.bmp b/src/assets/caspern.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5f68e181ee1ecc56b8530580fefc2c694fdfab18 GIT binary patch literal 270054 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

&cc13e^(?OASxiLQ0tSPZu}%np_+a;h zjopTA(CU$}xlhvezR6E8WP}C>6gN!UZ8eI+YcvfhmWpgMm@GZSJezF$=DguN`fcaY z@3@RU4ug;=o;dzJ-zgvXPh-iKRt3vVUxk&Ni!A**s_dI#3$G?Dyq>(|=J4gWN36O# zYW2O0wf8gE(WkgaM9K^sOA}z2x6w3N?IjUd0veX5heZifF-lgJm}KM2W=K1R9__V={>1!tcEpGM$OMB< z_6$DN#s64mzjyf}80_HvCePVx1~rDfkJiloWqt7;1}Tb)IP+`0vx$v4A0#fV+fQ{R zc*9qTnhbSO(5v2UO_h$To@>A2*>=kX!!`t^r7-vm@n@Tb46_-n7e3Q!fl3c4mQtUY zCBIwFGFnigfyBv1vq?s?2}aYgM#DIxez;L@s8Kh-sN*X#dmkh!4C^qttr=8bsn76e zg|P^2cxE)Vvt6mVo+OQwT?!$c1G1UMpZCuDi6m?c~R!-$Ky7cSOLaB`LYqrQJSO$KgX5cgTB~O?g0Oc4~ES6A!PdP z;Hf_hnQ|k5*R&^I(*SzQ^Vyd?bH4S+{?;wS{6?WJf$~bPyc3#my7CqKUZE#@hn?y% z^gYxq=vbG)cRKmM)!FYINNi7C)cegg?nh8-*H>G*9BS!wpsC$n7?f2(%N-JqsyESq zk?6F(#a5LMQj^(CTaeZ~0Gitqsy9Jtv|88IFLYX6wey6H^W`xr0wFsgSms&zKZ7-|L^8CAHG4~Dh>LzS5)fvC;|D;d-nY6iswbqET8 zEJ|?GzNyiGWhHj!JF04oGC=@rZDF(_6C@B-1sQx$7AQFD#4aJH)w~2lO(H#d@Jt$LgMpK>5>nLM5L5!Pz_$L zccX1l)PSShKBY|um$wL5$QGe4%fKM&Hf&?}VVk+ajrykSBqCLDDW154`5EZL3T4+m zZI1w$vEMfRAONcCqi-l5JnF>dncTNkR(Jviy=9v8lyCm2Au~S-Df%*`_=yi{3{#fj zgFmFMxXq9BH9rZ1Ywl&N`8g8|S*Bp4aNT2#A&BX1K|MiA!Z?15i46+`cL)Hp*8G{d z=8ufkkN9S-eLQ0MuiT~KR$KgBPIGfH_8_*agpXY~z3c`Q5rbIo9%@b`O#p6DHRvd7Tl-Gbglode#| zg2WC!N83>j^?6GebbD3Y(D@($HiA3bm%xyg1Q=F|_*06a1Gd&1u!V-8YD`F3hTqa3 z?6bLMuZ`8Zt*zE&EmjDFf}t5e+;9mDN?AqhC%&kHzQ>ts9*o(jN0nde0EUiKM>)YJCEzpzdE!Y1)^ z=pzap5dAUXs735Yy~9tK6?U?F@G%5{o&1k#wexwcJwE91S{sko6@vh{uc>;rp43km zwBF6K5)4XzP&Mdl_uEW9Sm}c#gL+(z(6m3u46AothZ_=_GPEY)XlrvUDqTW) zg@m9jiz>Wts?ltU(R`|kLRAO~fK79ZCX9^684aV1h7rPG15F|rB0oW|9$+ff4HO>~ zD^wXGWm39?@Q4Z4=7nD?kr~7O#*4iKK)%(x8r3=|2Adl%aB~I>8;GdP{CgXP71bC_ zP)qwDnV{}ONEBL8hvA2qAiEM=)ovyxh!xVEmx2s|=m4P)2HV*v098STIT?BrA~#`B zV~8PQg+!zjOR+*J%W&&HMFfMk8HOz;NS^`{u|;Y!^y?La{IXk&RVr#F& zE&Wq>43G`qU63f1nY2BuRA?WBL3RwCN58@SZ6)4gdKc*jDF{UM5#W%b)8VtvhR;49 zKKnvs={H27#G-KvE+sFyK784YtNW*<8W*D*USt$z6^u1u50rW zZm8RWU`RV2(Tsq>T75Uw=_j}mi<-yPu*LquX6?RPYxLSwt^0ZmktPL#L4~0*K~h2r zq!Ngh8Z8P%peJM76V=$vB*_5#uyF51VGK87~&AYQ0NPhukeWQM3xG@ z@6C+o?d*Nup5b(-_KT zy^^dou~#_6u)qoxgEk`!I~W`(hG>iBjg+r7+$m=iAH*eDXv%udas0E6B~3ds-eXWpd%IqKm>_|qx^|T5;cItsESZCiPd{-V1o2TUM=jtR-#Z1pf*HF1B+DT z34@c2CV4_4KbrC*&uEfuG#+6NM8UAZP*FqmB`%fRaHvr)$iV*inynBY!~|W9I`j&? zq`aYJgP_#g}_HwewNxh9K}=9DE9oMPgrJOxa@$a0NHWM4Aq)z7-s;PxHMb{Op>E$(BekX} zuNVZqzX>EE5nBXCJNA6DpL3k>ti$-{ohM+0U`@xn4^-+wq>p13L+>u-f->8#d*gO1W*PwU02OaM= z$hr#xPUv1-ksJYuKE!+;aa6Q<a8*g}m|7i#MC-=;5ARrE3H zQnXR@)g~5o76$cKFjNsKUl^2dlvq?V*s&rUWwo#}E3EtP2uGC($|Fh@S3}JX$V)D| zCs@It*dHM%0IDdoE~DDo1S^_@>`K6(B!jjBAnM3_XATNLHz~!4R3?ZCk{fnW;b;$k z1N96r`UD#Thdp7?o;@ZE5#lnRQjTHA<-_b}?8iOlH1T=Sgeoq4$7>Q{u$t?Xnw~Ri zdd{rvT~xzuW?kl42EMbK2FmlGJdVa8L>TNC#pKLtx`dF}BVnT`aT9F| z02Bs?Z|jRvwporO9OY$-JyuMR!eGu}=C{QJl^bdjJtwL=z>|*q=ARs#|31l}W{`>~ zv1n}hclaP*$p;r*jbCs%e&J>LDkUzup0f02@)9vbFeEXAL=7Xh$j~HCDu%+9fmaea~8nnNK)5|TL_tqb{ zwV}<<2G%?3TWzm5P-bHw3;MKR(2SuPU4udBm;y?i)&6 zDm7A?5#)nK!k`47Fo^fDC6Ov${e$0?3^oWe8mYt(2J45Kr2!-~)m78F6iYF|3JHd; zO2DWYv^8pS?1JhjeTtrn!7j=Q>DNDPg_0OP^Z&Xt^Ur~(M4^hoznP%M5C#EI7;Ghh zXcNXnSr{ZAWIRUi4B~(~7Nss~XJ(M>4+e2V{e$29&?#YeU!$kLVld9IN>&&GAlaWv z4DGXoLB94mN@D~-N4T3L(`!VYu9E@q1y|9F?)fizOs(!dt%gSd3|8maP*y6uitGE% zuJ2RQ&~Hv7ztZMG^I3Fi5wwt-Ge~3DC3bDk#7$-;ZH7JpFm=0VxMFbB?t#h&B^=FW zpW;<+J@G6B($}B3hYyBclip+9o}wr|IHce+0#O(YD>)B=t5}4UOU!A`GqqNi&H8AoJeKK<^Gpn14H={KtfHN}xYRmHZHa z{S{vyI`i_-g71Q7TpBX<(%=bSdyP5onR~$_=Yo6I1=q~8P9wh%*BkMPUFt{3cDNb9 zfr%%r65k&XcVa;7DJAUh1cJfd5%2X3JKh}tgWv5I_zvpqcN7d^kZ`n}?~%5?hmd0M z06y5v`Q>JgFSl~p2ZK%Qb~UlzU7x1B)y|szHrK!e`(c8DVP!Zf1yYM0;8x#qCjgpd zxwSSy>42@Z6o!x}|1W(cE|qa^GlMklbu2nX7;KVjG+{b4Rn#!iXc#ZCXoG0QASq$A zGQkQ4aYiuISs@Nc=K}i^c^Dc)iAWhARRC%$gh!nc)~v*^xAZBbS4cSeuMufu9`OCQ zgHg!@wFy?nqE)J?Ot8WSbs!3T#G;s>_CcahBmj0YnsVPB2D?`@2m1+tIu^wTJ8{#= zRWQ`Vb#YfexOehDF;$!= zS8QZ>{-uJUe`%Az zc`b%22BX9ZF+qeI!XN`|IuOMW%?ze)w;1&j09uaRZIi{|=mFcT1I}YOIP->c9t?7R zjcdT~xaRRj;R$)BaMF8z(->F#1O`Kj&V;g4Uwn>O6vfN~Ly1MB=Ut2`|5hYP;&*ZL zzl~pTY1qQ=ut=38ey=g)22|RLyGZlMs)cAdXS#1IaXkNa;(Q*F`GLnQV#{tu&$$^< zd>saZ3%(1Q{%zpYZ+ym|^%-~0bIci!+_N4z=iIZ;4$An_apb4=X&>9CVSgWBe}Z1p zDZZA&PFcjC91wR>1K2y_w7S#-r7{X%%>s>HdXW+IM`)oui$Ta7JibP5@f}s`+Y9yhuR{u@4`fuT@ zu$3}S^`7gh_gEw2+-(_{p;9{AXjNdem~1p3V>HV#8jlp28BF{OgP5QMq7@7ZfT~>x zfPx-@sIL+Q8E-R&k`h*6sKZf73`q}Z*)ul76gLd^7AyRFR#=f3QknTT|M$<;7)((6 zpa!rKLk*xg3Z*mH)@a&U=xf@=Xu+f?Wf@f()c|(jpp%nCq@63mP91!jVN|^d7^E!I zeXvY)Gd2T*mI(r&&i?R0!4L*>g+A?rb~(?m&BX0B`|-~?OsG0&N)?`fahrmwd*s*l zDX8UB0E2aWipU4CLQJq8FBO7bKpEeL0jQMU&4T8)3|ZVdbZN)v)r6xuA|)1OgoebB zx+o$y>^FP|0!A>jOy6yry&nu=&}qzTPMSeRM)Tf=L5(3BzFxdkIQb+EdjILX3-d*A z;a4HtwP2xsE+eBCATNCgpt?v`jb&di`VHQ##Q<=4AhvQvg`WV4ukMdPf`=D-3;) zaFh_VYrxyW;NUkq4nEq}`?a<{lx2>z_Bzzc^I&VQ!>!y8w{qLx#_eG1L9aA-++$|Y zc1JyHQH}nagu%WWv=!=D6tXHKQfAon9I1{=i9%}+*eurBcY`Jo2CMa03x?0M%{#;W2BHPSHEF7$hXo|!>N)EFu@D>0Pn zD6*G`R4`PDq0S0v6q+%7YG$UQIP-7Lj;ds^(gB~8LluKM5ETG9;aiyrRwjdt$Fx@r zb~Bn2h|-|%YeQ2P`cr9K0I$=guh;XC@L?nM34 zc7UP9NWl;W9Y-H=9R0eZoL_s(K~0S+2H)l2jOWDne5Ra|3o|o5g~6e-&V&@7!2tmf z#g<=;qDoUH7>3U|uf!zV`H0f9aSJX+&-*4`-0)h$qU#BZzL(+B#W#`{^JL5oc|K;o zV957r0ORLfN3msBBa5$u7hMjWc_pOaNQY24U1J(yE4>0o1;%giwVjHvkfq8oGez@ zkd{P@gr>SdukBA`2z`psH&qinBt}^ zqx$tSGt=%bqiYJoXXIU&fBv8G?6c~4?^DmXR0g7d15g-bIurm^GDtP10cY)5S?XXk z?`E{@DGcf!eM{Eo)tpRwJEN1MAq=_-gWaBD5E6++yXm1d806|2Fz7X_u1~Q9 zqWGY{n4mB?WG)!OAQ7otLBt1%MP->nM27+fc^r+=H9e??6@nqLC=6O>?xQl}ko&4b zE>`%a)99o2JefV_9Uf^iN2EMcIOP;wLVOSmhZd8e6~@f_CT{-4h_Z7qi2a4l zKBpOsp8Ivg9RBfKtU{GwHD(?pvT4ZunVVvWn4o&P0st!+ROnrapLZ>K&UcX|mw5Fl zeAag%M4{8ZMKI_+{!8!ir@h9WcFX;2P}Zj|nV%rr)KkbhJj>O_mH0(IBzOOkD z#X76?06_lS@M6!k2nMTkX1A9XAyYBA0$`IgVNl#K$)Gb>*`UY%1Vh46C1Eho06qQH z4yYMy;4dT!m9z^ht&m2cn+O0UD0MWTkKTlCPw48XIUJ=x+R8jWs;%((I{!={HPe61 z1S^Z8l?>`SOeKIa8^h9WYbnTR23zzH1~Ea@nlVwjgnCxZ>Is7Yh5rNUZN*@f^q=M;u#Lrczx56%$)5xopC&3TvTWei(zO^ZoymVdEA zo-&M`i}4YEUW+Nc%q3xNWr#|?4K4gy9zZPkZphSc{3e|rJn@{*gs;5Dec_t>@u2LF zU9vuM82N!++9_l++zep9nB$~=kX2E2c^3vz_mH>M_buoXg&pk?%I~+j4L#Z|_-#6a zU3hvv@LhsZ4Im7*@qSeWqK8_z@25S{)cKW`t_LJ5blD4ijqG>fgN+?t!Ut} zp?P+c>ZlswHcxS@>gYcY%ou++LCT?8l>nNfP%fvjqohPKC=9kT`ye%$N(S2yg(?7P z(@Tefc~S0*4iaew#R~C0`tqQM{ehvMoErte9_%!!OKSjV$$OwlQkkJsFWk|dNLR@q zNM?&0+UL=rrw0LmFS<{|1gpE}gI*2KX$Ut&(w^|5G)g#H2zvDfm!SH7v+MiuEotCC zo8k;tNp*n~E9A_D9LA4c2ZMTiw0F{W)Q4@R3IoI%T(H^ zN;hB_Gw*V2`4v_US^njRdd-jr4Zr6g2CrHu@y64)>baToJb)Nlcrj$gCI89ieJ7kn zn4sI}PX^_DQ>VRrNd_C)?*>4uutvWvSfO+rRDo1{u-_(Xo?yri{e?aOu$S~BXbuW@ia{NY zR_(q928|9&p6yUkoM|~t0Bn|FG)*&_V1;P7d|^<&nnB!9bqRHUuySn1%wxb`Fcd1W zLh3UbLrA1jN}1HjsO@0Xvi>WBx-3JJ0+AI~G%0jAYW%~I8EMVy1KPx&S{gvAF))ZU zfZ7LPu%7Bi=!&RxB^Xg-Wr-;@URmlbYT4Up&Ah0}2W4G?#)OTu2s_#v-MI7%fK)-f zl?n3Y2^b8Kmq3X^IW(#yXV#*mEHf}!Dl=dx^eGJGOK6HGN>Iv#jIP5Fg2G)*@9C(P z&-A)}Gev_71x6T@;>;{^LrotJ*f_AXfnQ0}pt+6w=QJHMk3I!f*dlllEB5*VTP217 zh!yru+yRFA){_N8YYfbckT*khv!005F8fs&w99;*pj3)8BDwqIHvVm|$;SftYNslfD$K8XYN2*vo`!TY)fAMFzKrsD3k&Oxtr8ghiM`tfR~AtD$AOfXd0AJEa7 zmt+tJ1i)6F`&+p0Q{Pvbx$bL78tAkSfnEb!d~g>bXf4Zab*y%PA-`!l)a=JRjP(8_ zG3>Je)$EPUt>Y^^_LjpkHF~V$%aBa1K3kv<6VxQa;Io~UKhs_VNLi-DXvOj%0FDv{ zn+`XcCMzWxO%shKNs7S)`Bv6N`JuBy9hVA*0Y(D`N>wcSBqH@vB^nwQZql}><6_id zhKqRbEVMB6{v0HtUUNpMTPq*J&UO>T)RE`N~oZ z4C+AiX$*BBs%tWp1sMP&9Bpf1v{mD3x;om~Nkycbb@DJX2!@gg`pMaC0#Tg_VuBVd z)U!qrV^}h`mMj2PGROd%Fi438B*hA=xlT6MLf!KzhbjPP)byE#YIsep?TZOcukA~l zekQJ0*S84z_)*W7;tWA)aYO&vjRNL04=#s63Z%`07P4rsFkH(a#4fQLP>+NyGCrEH zy-(r}9x8n*%K=gvh3e+v5&Nvy?3Ad_NS^`*$G`11{w=S`$GoQ;_sM^6 z@U)YV7*hN>g29mDFC_cJ_!NB%lqvv87_mi~iA1WnAvGMj7?%aQrxaCo2>~ESq7V#n zGYaWPXM(1m3&{T}V9Hsqai4qSeWpzCL+7mb?MMB8biMU=R_D65&BP&rgaCm65s14% zNCI(p7h<>scTa$LLU0T2?o!&)qE%=qrA6wx)_&hV<2|nXp3g(t{e63!V~)v_uKn9F z&dcW)QMI2&&HH@9tWUzHe-bwB6BtxJ_*7Y*g~4J05V_}l=$?1atMLBVoDY=VADeS` zT<-f`1s}WT-qY=PWqkLf3YzvlEeY4myQ5NWj!L;PGU@ur#2drot__X3I&|`N$JkrL zV{Y0jCaH1pvj;M9SXkuvfOZHWl8xU0FHn@NbCmV2*sczhEz%!T~nJB z-3?JNgh7R&$)KfS0ew;|RSaT+CWAT_RkNeIG%6;jd{8iSF<`LYC{Z7W|D6)PGeK)P z)XJdM2eCo`)C@Whf~qJ~2cp^s9X+H!hyx;VK;?rP!*P*@`y??zDl?D>gVbll3RO># z*_c2s-eZEa1&gH|8pgpx1t1J!g>Xlk9_|>JAt+^FhAD1HBtwi{tr;W)#Rs(sngC{O z9-Q4cB)7#rr)5YE4%j+0mugI>Lw37;W~)Os3<6*W0>)uETM0+0%)lVws7vWV_sU}) zRma&VWT8ohw`X$W;*tiC<$6X&^<9gJi*81e6)wIVwfGJvo+!>x8kMY2iZiq-_+AW0 zx%rU&qqL2m!eG|sFLN8eDr|mHqO6dh6b2FW;ecw8=4aK-|5L)&6H`%Woykzm~QB&ea;eJHs`_-1;{;b+6Ocy-Z#GGI`ZE zi7UR2S^W8=g`Y*wN1uT~}x(!D2srH_4zANmwOK-vdA z@;~w@_}C2wb3b&;hCvY+j?Ml62GxM5_#hRSF{yXQq}>6)(Wy5b6RwO*y5^X0)nW1_ z`{;|qVy_K}z6yOqqOO|sjXysq;vyJoLj*&5e{=)Ekot_aIS_*{lf;12Z1OTDN?*R8 z?@9hdK4^FzGCcP6a6i<;odcw_C%7%67{mw1)Ei^iS5n-;pp!*bPs9g>LA}bvoQ&F` z_y>mF8O$^sGNnw)Q(hEEyP`dM$KvZH;y7R%7D3k_0J~-YO8)0~|vc$OBWWy`g@QyRQ z6GY^OfjA%l(hV$DXSc}&6@y}eHDZF&B2;S>063A2!ucvO)I%~$dnK&xlPEKyjK^Sw z#GC`uHrr-3*ko)*wi%o4vK#Gkn!peS9dg=WP{*Ip2ZI_z{p5GYyzSIW!H`DbSU#d% zbrg9|XRnYO7o3{mL%qbJVuF0Up50zyaN+fdi*7_Nz8Sp~25)oXiCsb#2{nV0m(#QO z2mn#aI_A0`VuhMPtgrwKl@-#7&;=O{ATYupCJ2MYtwgHQ(3hV6j=w6m|AFxVpk|Qw ziq1a)u#75b`=3+V{w`_yy`<&0qQ;-OqbLk+dIf`NYhI+Td6BXj2EUrT_|r)XKaHCI zNmT7;_+aR?N5bILPlBsNz9kR+N+0q3CxG|h&b6CxL$~a^LSps@<8nTPLDh-)PykH5 zJ396D=+s+IDc6R@UmO;9X=p6;T^Tazl4j68>Ix*~b-|X3d~OZX0qe=+xe4eezF41i!5x#R{fQA@-PxiAy8=!3|GTwVK!FWNK4#R6PC8ajyph)UakE^hx}%JyF?cm7_rgWyvzoYMKb zXzL$U5{Uj60OZ6dFC&AT^{mLHrmkWd4?C+jO{ykz*d=Lg*vhHeG8H7Z)toIp9gF!2R zqf!9y`tXEHFz66_9tMZTUUHax*)HnhkZ1vL@We}?Ck{B_0vPhN8GoK1aYH;&Fbuyq zFy!2T;IjilPWKHs)d%_%hA_zblEzT`U=PnD!l35?!()$Wg|3~dQ_rcHR>P&4syKjEq8}wm<1j;C)1)>{ArVR)xu+GDLAeily2IRqvjB za1f(1YFg%B4B7-31MxvmC3m6E6s-!U9{*hFm9B)Y!)O!K3|gx(+61it{)<8ALwZt_ zb80Xs%?QOH0BU(ei}(2?3WM^ZOwcz)dWE#?vBDra5iqFSQ10Gy1D}J3)shtogQ^x9 zHP?ui9I!{ss-AIcdd02jld!H|(uO`s>-(i_M1mnEn6U*0#RRiNHkq63bDQzOq4{kT zXNKiKJLpqToS|Jfx^$m&`GIlON08U_6F$?`rHks5FvvGzFhS9r zi+sH|eEww=wUmgID^GX$jBljqE>aWSEH{ZXiA1C+>z{z3P7lG5VkzU?YNGpX*;cxT zKLDU+kf9olp^&)sC;Ipd*r-|!b8de_Us?NarLDgs=qqdeyS(i`#ZAA9ntugD7|h)G z5@l?Bk-X+v((0!$7{C0>s0B|VYoA2SeLQ~FZIRiQ_L6_0#MKBnersl9xp z0ffPExgWxvbH*LylKGx1FlOFy&3X?8dAel0=bZi?At(+AfWs3mk4zR591?R5*-tuW z7k$ny>H=1%7`y_2c9EAsue-pI-^mTpfY7r%`v#rr7ks*Rz=>YI$9wx8!wLyX1wG%B zz=$wDVNk4apW&f>kZ^RL;kMmygG7#9Y%xa77XU@L-qd#(f}~g>3|7cfB2v|Hm2|C9~=Q0hk1Kdr8RY8?P-1_z|q;e*INrwJ>hKsqG51uKNX;rSF{L>fcr)6!KM z2H5BuIu-98UAAvb`F;e3?o~(eK{>*vzS9JWq8Vqwa6Eg3^Dpz1&8FIGO4lP7-_c^2 zEoS8hF)QAW<+=QQ+%SdD7jAeAhNOoQmo|J|*z&Td^*bu1yBIYdoG#s;+%0CY+;CW4`|yITM5K=SqLKOA=}I`ztw0tM zX%|Y@zHlcPBKMjjd`lDtnPlT5hTNaw3=~!Pg~E3`7$*Y{X2ufsfhdmk}q1&-Sz7$SM; zvS8S0jO#GQwix5Uu-S0kD2B*$)Er|JiQ#nhoGJg*R;a6{!&K^LHX~Fk@EwVYP23Qf zjeEvsnBS%=!AkEWbDdCPQ92Z%hHcP47{vZGg9AO@G1za^yTMTwmY@&rx-&Rnkn{xU zO7OHsp<;qgrYMIBhJ0eFTZ0}3%`}j&&qtb7P+bef_}~uj13>H#0JT6bfJF(yQ7&&| zhi-2D6m7z%MrrY$w%7}CZBm139nNm?sPT#FBi8>Zod8wO<55qS>Gs2B8d8V2#q zZa^f4k{f0>I;e2Gy9^W@s&E>(FeHL8*=+S*9r1=~T3vkNNUZ`>~bs zF<)70qEcFM3=-uOTlGn`>U)+?RB)Ob0M&-?H5d%9y^0tpg}%t8x6tGj@5QcqA0@Bn zYuX}6Oj>(CbJM4JO^ncdRoL>ppczAaUef+;Y5R9YZ8Q)$g!r0Uh>(aO0;B1Gm|(}R zW$nLkD43Joz^mv(_x!tBA@FeK<^go6P_Vm@^=m~ld(1!yeNTdQI&?z^x&__hN z-EiMwxPxJvJYf(wL~h)cQ4E5iDHv2qA|xV>*f1>5QhqUQ(dvfeh6+PGaY%~l4^k9O zPykL+DIw2DV=%+p9D2eE$p^7QF9YZfDQHa?)n=$cE}el0#HipG{7 zbSpc^C+w{x0wZ(XnnC$k%xr!2;$ql*%TV{iYf(#YMK8OJG=p)g-%ncq5lUY7aeCdO z%uP@78o$VIdRoxT;WbfyBej}mC2cQhQ!LS(*G=>3{ z_k7Df^e%ZHc^2LEEPNk%6xnh=GeSjuDREpv#*ZHyb6Y+(yjs^7>>!f;h1s} z4Nty+AaQ8IS-Y5%Hj&2$PdYg$`ozG9V>S~{*iJlU7k$<)>O6^|&3JJ=6TP4_Qg!h^ z33omHjv>S6cyIqxaK{Vk;Vr+A687>rPCf{0kl4$MKvdbE4oBskD6~VKB!;5xB6ohl z5SzsZ$1E`!96i$*J;N9^&EUnfMYilKgva3^mS+sh5ey~xghy*!ss>8UE}<%o+Q$oq z(xX=x>JEhf7$UM!R%k|~Rt8-pJ=DFzzN30rI`u}c-X?%nAA~^yQ7|+~9AX*IRwf95 zkSG9-HilZJwE=JxAKUd)Gom5N1X_F^i4(r6K_28M~-Y^4gw>s{v36`sy`?nnZkXa83gv5S6$zyTMkT zjkGGTLKqyD+fFhlfoOIo#9@EkG1LsoiaiTW#e3y@zU5u=EbG!3LLzRc1%_O}FgFcZ zHdG3pb0K^_N#d0W3$JMaHG}bMK7hW&b@xze-2;?X_aL|Nv%ID+AhDnsL;O-mZ2Agk zEN+!q8da_#7X6{5l?Ed8{aVuYOIZgIDGL{bqkr(i@8X8SpeVoLN0htyZN`T0GdI3U zUj0I}_8aYkFgSVP(}{B_iati;XFUp^@hEJ%SfMaj{yy?4{QwNTitp;Dd%^8-1vkfJ zT^^f%V@%c+mz-;(Gp>wIza{{t-yEHO9a%B7k2`G_duq_+6Sh$&21TD7IPsWm=wW=Gdkn8#h9`gO#vm9vFEd6{Bb_Y(qA{~Xyg1hyV-^~tshv`vDN-0x zgux2aRUHNlb&{yVQJNHbgc}U8!X%3us!7S zgh4BY(5ErfK4_;`BvdH|2E_*zfHWr1NG}-^b>_0Y9@q|+awu&<(m=B-5i50=0L>r+ zqT2q{OCY@oK1Zlx(NH>rMMij;F`kR}ia{~HB_@E{1QV7S@hf|$tnHPwrcd%ZqEJdP z12Z>C6q;F&2_hJ@CH|y6p)??4Q{R-01JdecW+syn?uNnXjdsk;WVQ{>;-W?SFc{43 zl=o~Fdpk$uZpQ~TgL=!}wRFFmVsP9PzHToc*GA(ij<^CN>rT~_Yfku1=SuL2z}aW{ zVufZ903#M%N0XM_L2;|d1V2t%D-H;W-5Jbn{5-eeb1+o;GOyt&Dr$LA(n>f=$y8!d zRUrMjj5)LpA&~|>0Lp0^dHw;IR^>Oo&1-m*Cq>ck!7ydbw@CXS`C#mlr;`_b5hLN~ zW26}joknHmV=(la@&PhQEW68#cjtoVyj83}&fMkNo z2QLnZKWiU%#&*&Po9N>MBTtAT0Puv(#FI7=r_g}$C;9{*>m7KUjIS3xzQEHsAPhpE z;l0c70lfpDXOiW0Kr<+Y=zX-O&#_+AVLZEfk_mbp?g5Vg2ysZeo=1n_1$u4r6byGt zEGi_bxKvx=n7I}JryFCY3xF8nnArxukD^3VWH{o3+2V%6Aa1Dp6qbCDb|Jr*y$N=j zXc2-TiZ|>ikSYcTkrn=nL6r~cim3KM-LJQlW!@!&Rsca#*JQf;AmvaUg6gO43=Zdt z+E~NM=N)}4O}K`MU~udNVG#N##UL0A$S{JkMPMlOv96nGnxJ+=4Im6gz+kNrx5$Wx z!6iKsmYXJ+unYkEq^|3mDrq1ZkY0}u>P(O)01nLBJSeBpHoKvJ#-{#hn+BwBhQa=6 zbS^dx%GhF?wiyQPGn&B=^mM15=a4K`Dw+2E%(H8N+;ufs%kFt*6VNhA2S)zeK zqEjtA5dd?yyhds3Uu10jE=5J5$!ngYgcZ+Xmwv&h42rJ(bmH765wo6*pGk+}ad6Fj zE&qxSyJHB0K4o`3i*I`t-vL8R&^haxV(=PPh(@J}h(aAxE;%HS5{mjq92+?C_3_;BCQqcGSj@Cbz$a=jitM+~1shEJE_vqt~~Lj*fWV+C$L$Avy( zQ3*$}ze7SF$sk6l|4XlJ2J(hG_2SuSGAREaR8WdtN{NP(ze|kKa|JgX(0R7uJlAkp zsNQQ8jMQqVj#?NL05L>-P>;&wziSjq$B^IY4<;)&j28w?3?q!e5yqe}V-Oeys>+PY z2d(8$Oi<^8f}xZ6AO#s~GHCTd7}OZTpl%LY0mS|!3RQI&98d$OcLwo61br@SE$K0E}HI3??i!5?0`bJ>ns8 zX}`4f{RF@bI`Y(|7)_rBa9}1FZh=0nLD_86H*(j4)}bAn>S0oHGeQukyqYM=Skr^$k4+ zeK6Q3x3MM|cW8-rEhI-SYI_DJW^Uc;bm(2Q-7U2nj@0IC{8; z*AYY9kpCg*0bQs3Z}}g3v=}fb816E>@J9=S6l!3Q4#k)S;(E^W6ob6XQAk21F)Ha{ zjWL4FdYu)5o;5MFVo2>&m1TJHSG*DowGR@S+Hr4ZoE+ z_XI&NB-aSd7Yt!gV;D?tf=sZ$2ro71i{zS9jnx4KJ<`C06+PmX_exyVH-#b$_9q&c zQHN|Y>us~8Badvdx7cKDv4u6If$0RLO#sLmg^opS(>D*|M-`C{N^eAiGn$0KERJ0? zfgvN@PK7&}TZ20c5de9@BMd4DgDzzv_o~BVD-MpW?DCv?L^CL{=$vzM_elY0We@<9 z*F8vH_mF->YTe`1`bVjo9%VLulGF5gc7rHuGZ=n}G=l`943rkNd{@-`3I@ps<)dj^ z85~uCXeaR}b28cofe~{QXN1ABj$epca~od4VEV=v00@RCbsa6jZ<1C&OIk&T0tP>i zU;1UtqR+vQ*-?o|RgDx3gQtDO(|5{U1cn+wp5yXw!63yMx13vUIX7LiZ@6Ru<8`OB zOCwV+jY`+0(euL+F2bNqUhrvT?I)47pN^mXD16pKVQ{Lr zA)ZKv2z}nAQk;>>Or8h;L67H{%*&%QM2^Yl9f?JgFHnuKr4upfw0K|GF=PZl-(e%* zpb^johMK`1{s(#oAL-%WW%%zm{Pr1s2NZ@o)f4DCB`%c!6^kT5JxDl8&WIaI9R@4( zJ}McaA1@f?Hi1|81;DL}LH;LJ5!vpxq=c=iI!Xn`!l3IyAyGS^_#?TYV$iWvtWdk5 zrtcktrH1^~f*}kd2X-hh!C1qNM&Umhl)9+y2|7z>5DXdEe&>T@di1iDbqP{G%uWN? zJqqPVDahEXMF~e^n2VHO5CG~l5Df7?7}O56$@he=xYJNBoN339I`i(GXm3N9zITKrgcn1_$SWo(K%7g;Jj( z85}4x+tg$v3e^K_FsSJx9OVT!BqEjdUJQ}5Gih7EaA*$KW||2~ncp5s=OU*Q3>jVH zMPsNLq#z@eQpF$uj;lHdgQBU&@IkXEx!1kpr_^C&UQ{#q?x|b(;)7dW=WKqh9nkW8 zNvA$z1AU5b7#vMm^&AXQ5>woZK4X)@iec!C`zWC5Lj-+ZCGP>CN8ug!d=d6%aX=Eo zDF5D71Gl!6#uSxbbp?Kon^!Uj zb0jqNJ)js=90`esWKPEal$1tw1y%Jd3||t-y^6jL!xtC{L2*OnfD(veh$_3}7msbm zxK`D#r%Sj&f=@zF=z~G=K}cMz+)yz{;dDf~0!>GxdS=_wzSs1DAtEK@sUuRsFi|mx z34)=;2c<5`xSF1g!2}h9f*}#9Qg3@Hieh=Nri(C|L4MIc0w7{tVhG=oPz*vJ45AUN zDRI-DYK&sg1qWnQ8xy2CXmLPE205h0q6BM7$^IR#v%~VSJ zrPk>sCLE9u6bF=N`eu7_LyH?qbgHgiFh^>a$=#Z4Y0*$LUL?-AuWj}&JL@cTqq&-1bf`SYHqL`I;=?o^W{g|eFdi@iW+3=~A!NT_E z1#MsFw|>R5pyjK=R(aB_*D7uQzO3U_dFLB8?%AxTAy_4g5>gHYK<>Qm=W#cjHR`h%*;yvf=8#tIn8o?kzY5cOMxFPd1xFI7nxM3*W zifU=x)2Co~hAtr@3U$qvDAY}|!mFdwFOJS23cUz}!xGO9OFV}U+D$&)e}WWYKo1Ah zCfF-T=+n}PAq=8-4Ejre+QaXl0O+fqyuc$m#Kan|N7r7O^=u3JpX%*@vQN;7o<j zJ53YB3e8w_hg5h7Xsrn*Y{HOMA!N%AyW1OWTs+W~CfWlygGz0@x zACOp70~nfTOso)%FB22g0K#B2quO(bLNP(;>zS~MfD_r}HaO%p3VOL)h88r53Y+=S z%3!~=4N@sh6TzJp3~B&j5EH}-X%w>CtGDc75CGY1LIB7Vw_M!R5%MH&E=VyI`2G_Fm%JkJ9QMllsA6e%rIW z)~6ak=qm)kRsm2;U~G9_+VK(zgIiy-W2jate!&3|A*ed^^cz>9YIboKk=qwPYH1Af z8l*0Y6$*xmK9j)>uQHW{#C0#z*M7@NMZ$_NrBEa7`!8_AiSs@Qr&2nTO6h~Zs*k-( zKJYF5h-N+0G9Cr*>txU+>zZ3G(=q}eR_K^~4hCt>+sB?7JP8v#+AsWQpHNai7$g>z zWDxZYJ)+e+m|r9`MTDcEM2Utc>fwtO!k`xBNU+*PFM}c~7-~ZVKxWuruy+uJ9nwh^ z#7ZWJ8!G#g5-V)(Hhf4k@kC{jlxxOqGFgK-mqjLk?-*3|QVORds{}D^c_xNdH!KkD zkZ`I*Rya&mZ-yio$ew*(l@DqLX;MHR;i%3BtpI|dFv!R2d9g7DvL=t&4H56t3<`i; zwpS@3e4O&f5nh~lG2!=>XF-npERtbGD z7*!*IC;(2LYfPHkD`{09OfYSIuf)}qVgSt^01KLj6*dnqY8g?|#*>{5-?Dq2g&zQ*Yxb?Nxsng!gRau4ry4^ndU1HtS%>)3Lle$8#GheM zjn;g>@FRUf5BCl^q(e|x>lJhm^!kRltvACoqZ|TB1|^ z0&8Mn$Qx9S_4tj z2lXnGtBN_hF{m-*sipCRLCP}P2Z=v5hS;B$HbI`4pc^fT5W{_f;Xx)CDJ=;rgSrq3 zgW3lfi3u%~G%&2t2rm%;Co!JQRqd%N5S=3oPOfECrccV6ffxjz~E-BIUfsa7Y}nC{}o~|9E`xQ16g~s8_JY?O?w!vO?TYGk5?DDb5g% zY99o^KEYVqF&NYs_VA-qv=@Pn?gsX!UZmlO zutF7=dbSxJ3~w(t#w?bp81qR8N-Rngs$)^*gOp4mOW?AUUwF~<0i!lY`47reELtFK zePJ-u7?xo;V1+SCibN7aCf5GJpvni|F{qjpu-4rNt@K%6bUtV@sIT}c6YS2Q3jhWh zZUmx=L1IxDM4pq(wLu9)Y0#_qQ!^-an8J4eLSO70BWAV{#hmtRBZhYX6!l46Gca@G z;M~na3L1wMwLqNKn2K!(21k~4I1~tjbSMy`+5^@2DBVNmw`t;Q03GsLU=RR@7q$&6 zP|9y}$ZKVjLe_ip+N})o0(v8gwv8;_?o_e^26-7>x(i7Hs7f&~=v=-J2C2z-)Ex4f zdQ^On=HTqJ;RK@dFHKl{W#VFnMQ==6aT^Tva2l=otSz4+nbTHgCj+7_Pfe*`@|vC% zx4$qMY=1Fj+v|!QZ!33jeoan4acoU)9`3>lO$V&n^&bfD$VnR zgk?<2Fhu%+G$wLyXi*f!1f9|@pkaxp9pX<7OFRRE_A#fJ5$!+WaKG_~`i39u6V}xy z^dRaR29jNEbunKxOpnjS@=)X?@6iD||P3;*#OYsOnDGUmR0<18o zd{A{a#0OOoMi@kzK}>L);lA1MZ0W`z6_}->(L|&msqD`RBmV?3u|i#$v6MhHeLVH= z^52vjBO#H>3~haeYLbniiN=sAoQVDj#eGz~P1M8be07MPR68M{$PGG`EfYCN#2SyHn}*QDr;EOxZQ2 ze7DP#y)dY!xB<|@-~spQgVLR!al(JbDHsf$$B@hg0Mv?J&eFu4gtZ@Hf=DwcL!l4{ zi538hJDzJQ6@ZjOUlg@{Q_}G*SZM$&cc@FGJAURYur&nL^yw%6r4q5|_r)D-KQXcP zy(EU4l{oIS`G>sC!XN;`BR*(lFl9BDE?&T3+)@@RBqE(K=MmGSx@+${1qP)m>@M{QGC!6j_ML90P>57k+!0D z01j6sI4so|nqUeB5sBgdAA{NoyEAC3l0hqd`o+qijzwW`q=zwz(NG_G3WH2&lLjgi zBoNiHC=7}N!XSIQafYuNRMRa9hGaB-n4kbyEOi(OK^1*?AJAzN)By5KSUezW{h+-1 zA%%@Yixq>VZ5SUKt$Yv$hZnbK2JH)|kv3{Kl&(G9L;4pY>D>>>Z??~CawupST4-XZ zNCd|Aq516^!=d>d_MDwz$FOj#W6{V511efYE9iu8u;tfJ-^oMmJn1wal@)zKb3ELQ@;Ieaoa0lu>Ey@6AXTz zuQ24mT28&VAz7gYkSYxfrmy=hb#$FV^e=Q9QPH;t`!fReDB**YRS&{o4?oJMM-VR(!BTDwL<^0PJjoVwLS8gP}O7r&?D0DVs94!6Ak}VnG~fDh;%!iG>~eH_CcahxSKprBG1@`D*j|w zVxjODx4_DvLvhovk`^q_u^WS<0I-Dgu*E*V!J)7T21yL@LEO+LyB^tQOZU(gWp4&R z&ET*i@j=I;4xU2`#0Q5JbO?s1pu>&}Y`I|A3Vj+wtWf))l|lOQ0O(fLn_b*fT{0x9f)J1=g!%&?+lyCd7gtMhv-xjodm*4bVVe@MkENFNOgDM;q zH_Y1jN}hF0bbkkf9N$K1YdFFEZQPQt6P7)XS@e`^GZAy1u+|h%^#OBh%*-$^3WJ_S z?=h|>^P-vLgO`a&0dQm*Dd9O%!l4PLB_)hGVH$Hw!LVQWVVjA^ zd1?%e!2Lag4)hG_G6ErSuRKLo`gZpS*xLg`44}!#Tn){OcT(0V{SL*T@;*uZFhqL# zdsKl`O^}Y=V2IWkZfi^i2|HbuDCy3irA;qmGjk0XbgD8-E~XDE0HrLWOi;J)^>num zL^XrMvy5R$ia}ygBGPUQ>bj^fXbDFlk)r4Tb>@O}Pgg$mi+)-|Q2r^`V;uj@AXaGR zgIx5rHYP|0VNexCHG=?%0#cwYSqhnERf@7->x>X)G)2YAPtDh9elWulfQ(czo2P*ewnsc-fMO=h&>9qD5D9S|S%>yl>x0qRjaR2U547kU}GEMv(8X;Kh^@|5Oa zor$3iNAX0`K-Z-*u+7t%p*4je|AfI&Qw2j3Jt@3&Yt{pxh~5O%(QI)*D}cNRfEg+! zRN<(OMF)pl#aroY#L6J+5(6?f49eZa z)4o8=4*GOWhV+ns0;VvSFANfh+T(*%W`w~_HaYdSxxyggPebs*+(veLhvv697PXHk z?m)wf+K1tW-J}83Iiq7?$EZ@OF+0bU?HXOS3kF@L?9+XDqR??*Sbe}_+93gO)^WdC zC;exgLcw#-!{GRZR}cWwo}eZ}hazF!hl%U&rPSR|t-GJyh!rv{`WXU4$qLOtR7#`T z4T(rg6@z7+q=Y|H1tk-N!J3`FPzar|?>88nzE=zp1}WF*@lh_Ym3GKSD*#Y-@SERi z2D$gkl_!J=X4QSC@2v@j8&$_}{hO3k-)RP87k#Z5lncON(;p$VW&a@qGpagzS5;bgWkEGp>Dm#2O)tx#h~$wk*fRa;OT5CEybP=~QFC;$?U zk`hvuAtg*!u_!eehPOF#$O<9jYI=7``=Da5|7bH11w#mz4#NkF+F)>4VVk4CNK&~~i|7<8vB;4nbS0!9g9*YQH5p}v z`-nerKmc^796J4od(A<=*(Z?y>{9`=PtzX^slA{zVewTIwftuEid&Oc-HBQKUc&kh zlj}Z)!PNQ(Sr!Jn7exUO6}5g{wiN)SIauB)b23vp^~WhB5S_N0*8ER3yG&K>__1oo zFZ$yY%!_gjn8T!;zmT=xwjT-_Uvp)YJBJ7WNeOefII0AOyntcq+81f;+OPgDe(7_3 z5C&1?T$4fe3iWO;)lp_@<8SjjA*d`vW@nI>UW~F^(v7jp4Dy@Yp2c7ms>l z>b`00$ggBef(E^2koE*W z^6a0!9t_3)sDkEiaVToyN!3(D_LsGZenh{FI>E3TgSg>f?UH$o1f@d@T42zz7(eZh z+_0!)L`kP(N#}^tZ9Ms>WARo5gCk3}jV|AbU{C<8*y~ccPXp*R{iyehW8O24`pi5Q zF!z*bjsQr15CFp#Tne3kF=ELztw}3yMX$UWxAtz*#(RkyK1`_>2Gch`%4+&FyYaJ} z#?NUH;(djdIT;u%ZhKzd`LcZ5chZ~K{)W;hAt;)*hfhxYDpBYjMrD4I&YMlwzr7kaCT* z7uAnMq1(hIWonf8bF1OeV7PC52cXAh^-s`K40<*g`~rhk3|;0~d{8YCVukE65sreP zBV`vuXoq%3A=GA(_$Uianq~nUz6} zp8gR4855OBQDmg>czrff|wux5{m}I9kbcgMb!(> zAoeCKJ{VtXBrP_Qmh?hpImp0vf0~091_vrD#0~B88<6;5eiJ$4&_b%CEdn4U7H@Sb+di^v`{?pr zXhiWgY!UhpnV@sUZY`I}y{=W%VfK%$=~DC^^PP190Et2YFmT@Kz_|io@Vs+DbI-xx z_(fMxAROsb5 zyy7Lho(3Xw-QTk63xi3ko+qvRhHp~DEP7^*MLBa3RLv^Wy})V~dpUDKW#*Q5DTyHr z$_rKqhGc~<*=+J&8JTjKi)yk>uNbtCKQ<)c7*+_0b}`2lhDRuwqCVmKdx!1o6{@X} zYRsM<0TgFw=pUp+BW?X)X)MxDRPn0hhDLy5P)OXPr5M~UZA2NZfkD+MgfD@v&KS2& zp|{@fSSRwV`-jFZ69?217>P@DiH6FIN)ItX0MybL3VPO9RE41Upk`23?^!2IRnsz@ zzV9}(tyd?oJQx%VofV1BhK-LIrs|RlxJf?9L3?F?nnAz>Kq{g-5VbO>9nb`j;tW3M zXU>c2aFq50jS1g)!#_zF41v4McM9T|A)zV1WE)ItPbf1I2}Bq6NLtoA4c1l@k@iX! z0D1OKT`dfzuH^T=>1%9r>kzF93N?s#o;DT+X-3FCFEiVjSYciNtc_L%ZF4q3pWdw) zRz#DrePr3zQB$^$s@O52tkY@A4yW=Rnn9=19kd0I=JU&<_0jHq1(eMDn^@eA?Mf_=lNuTR{!;LcOJjEbcA!9QNK;aFr@ZJ`bWGK*F;%-qRqO;YxI?4K z`zrU2o!T{SY8O8um#RIk)qCBice&3v=soMG_pD>Sb4~yt0zJ*3Jm;N7_#h@2zVLFG zQpD2h5zDS20K^L8*S`;gJauA7eI~PkHHs&BtzYD~eaSPg6mR z!A(q%G*HQouY9sQ&n;iYpd^EeK`F@4o!2>_dTIt~(+h)yqwLYE)d`OX!#}|Y8U&dNNFKsoph|GMLYXMXOE*ohx^`RPA!9-tAno2LN4a z_PSK>1waB$GCr58eXiB}$4x)zG4qi7%!9~d=0VR{hrDMW@t$+kcg}IYIVXbVpFx4O zr%~|yv&st3gfF@jy5K_iLP-WgNeLHRidY7N*RjHA<%5tY0B-nzCqZf2<_9Rd`ID@s zCs|FO6tq7@xthe*r$t+zn+)z!3@Qw3c8eP-{amx_X8@eC{SCuxTBT~yNv^RefgwDy zdsx`~J?IrQztqav{7v@eZ&KGigF)5_EdV~_+6-gcu}i+>1BH?ESfF?`Va|gIv+sva z|1fwe3<`z;Rd@WW?)Xf(E2abyM`R1*7xI8_Cu86gZ>kkr33FG@w!KEkjI6AkiLpuwP< zl7&HAU-^?@=p+4i$@@kMeZ2DoK+PaOqM>XpseF)#6d$yfV$6!D?o9xo5->8c<{mC{ zGJbKwU~sw-0&Zk~Fi2uZAew4gAq<8WiVuinJ#JI?j-9rD z?DPXzq4;2>Fz7M;kUN@z4tmTw$LvEswa5JDpAgla2wHGDXn_D|G6;!Ep$jjB zExI7jg%?c*7hamM^cvC_>Tq=O>f7<_?!OWX1wz2RX_>!-P`pXIiGp40MK zPRr*79nbRHpRwOmvh79LwwH*Av|`6A0Z>WjhGc>=O1kq0{gm|zim1vH)rsKm*#Ct} zj+7R*SO9GOHn-uM>@Ck>Fm3%;Y3rYB1}TjKpuYITLtRCDdwe(ZPpAr}PU>8Rti3UKp7UhG!j9&d|Oep2(St zb7)BHX}ifMVbC`ESpNw}`i(!_CyW}YbmvtdiUUeks2MbZcat{u4%>@*g$jwt2-sox z<9$1N`0qD-w+e}PA_6)wzE*i^0DW2w1cv%)GDvZTmOW7@YrOMJxp3WriM5$ZSYeHj zIJ(*xO*l%&knvH9GylRc!xD~Sh16sc4TpHcK@W>61_uWlg9C*%8xO;Vc^L9RS`x|! z2fCPl0!Fw)nl+7~)dV$zSmFO>&hNuDLDI=r7YEaF}VCw&3&=QVX8H}nnl9vEr zzpS;WZ^jytgrF<>Wv=O+wz6l+^1d0X`)92s93>V7z`?onDa8H|48j^FXcfg$Mc)>? zf-SnM=u}Skp>6b(?c#vdyIgB_kDW$%x!--p0rwdMnO)X)+A}xF9D{L52)X0#VV_BPX^^VaM+s9Py06@2?d)#O2bDy!_b5@tvtb?92yWD4X z5pCj$-gA$7&OVHw59k6Gp3*+Z3(^b*FFF&l=qv)mutk6dgBL;xdJP=B5&cIju)3mEKH^iUY!nVX#sdv|m) z6>4n9}Z4xph=!Cm6ca z>>N9N&$t_vX%*R0LFf98keisq!8Sy5?PR z&b=VYxroMOiAJWL8?ELLv_6L*AzutT%ibghAxD)$nOHd^t74kr{Xd!xqDRood!^GTfL| zV^B?1V}MSiOb`c@7bQppLwVwZm1=;EuDxy=vcZH1O;w9|owL5og@EMO(jsL1IxDEZq8a zVaM~b9p9Dj_#Rd4pe*wP)zRtuf9|ds2Y#8c|JRuZexI@bH(8yaOez?f8--v9jMBW= zPCMhr%I!Z_ZU3#Lo!Tkq*M2H&{*et|z6%3`8M02umno!6D7%D`8_Jgo6P7(i@ypqy zc&rsw`#4IDUGRyD2O%{NL#I9tth^ss`EgLy{ov{cJcY!{d!&l4`InGO-UXN3i=ymH zqchH<5h~Ynz;DwDRIu}QIGE=H-QTq5`*f*Tw%>Le?%+E+5+LLxh zzz(KpRI7qsA#MnUjUw;OhR+s}Z?oaoreJIl27QP^n@tACt~8K4HJN4VtP?4rCULeZ z%V_!_k;;sYMRCLFCWe$rWt0>WS*2IoyKGO4$Tu{DdPa0eq~Q>4*iSI*!$er2W>8W> zcafAvU8P1Uh0_2L48oVVp^8WeN+IzbgQ`HvpSm-s0faup<{;7xj$?B$Ttpy>d}G84 zgOdN@gIFQ$Lg^T0t0j7M$7y1<$zUAIN(+ccF+OdDk^^S1LpHe^`em&ioKJI*LTKG! zwwVgp7OaCoGb<$i%$Mws2~vmR=8=_K0nn*>>*%T5TxaZbosI(vfSN&%S^K@_botgE z_NzVO1AX(3_$c`;knGQI!3iQy=tCh(&W0{M8@B9x*iuuGtFBI5c_nhi)rjR+pe%gp zrLZLz!_m?UX#BE^6P8mBy&S!YTIlu3t8a={F(h**cI_P)Oj!3m45rmT0Kl|O4>Ptr zrZ>Ud8t7?J8qIHiTC)8G1(_+kURCURU9|@XguY*)>yqu0N10G41|| z_PyR_vXUrmM9t<-W@&!m8U`Qsm1CrBzwwzuK9rWX>6e_kp9DkMtp5%MIfMv~i=Iqg_(}BqCzIyOL^o43NZkkK`8cEoDg{HCFRgr^!l`@lRks2QhS@AS zog0&R0StK=nZ}ZZM5N~CZ|tcd47tVNj3*%x6VxMZrWJ+>gS|p%Ptd~HBOSva=~GCn zLYtrl(8{1+i(;@*JzG>t*d*~M(sOH!s3AG6W@%3leCqlPF97Jw8T_eYg5rZy&H9W^ z34y6hBoy2!OgpsQVO5bPo;@2IX3sDtqFF zTHW0c7A)dsx>-yEbn&ybA82LUi3K^Vjhr9hf#(4^ow zvCN3Bkzr996B9V-R4w-_*kFpq3I)SHnPi1)v^~+v>eP)a?6l#=&1_bp0~>@b5~$%|86w+{1s&G4dobvh zf4RFAIun;tGQ|p$iAbew!7UoQxD$++4ox~UB!TtA6ZG*(71dZN3m4R9XcW?^XNnu{ zcB@fRrq?Kq(j06ze5rhr3|dXF!SLT|GKe9Hz_8hHUv0Q!g3ArJrDjLoN}?H#>JEis z&~=94N^u4fsg7y}RZvP?s>4xv78@fiK8O`|2as5F$avESVNhbxZe2n#K>)NcNXG$D zZ?Q6n6~dj4NHv4qQ$j0)uH=CJ0-%UnYS721_5=Y?`yeK0O$p7)3};1ij3}=7a=@_0 zm^57&sLcbvETA(x&2{jMS$ivH-R; zzTc}%tG`TM^%TV|{Ygs&}UDfCgGG_tR#u-S?Cqu{u8Lrbb+C1g)-4iXP;_} z?ohxWlu>>m6KoU_h5B_U26aTLF(guDcxI(BZn-g*5j8gGnTpY(Gsp`mA*E3O#1M%{ zDa%Y#7*Zo8D5YhuTNQLGz>sj19bOnDE6g`Z6b2)e15Pjj)Ul{$P-0QKgjk_+Ljbg! zVEUj25QD?%sLWWc(8{1L&hWeL)C+^O=_!r+34J>F)K35eL(QO%ibcf)Q^W*AGmMFa zMpT&*o@-31Frq7rNqlR*NUn(rgVnk$qjm{r8}VQ`5BgxRf9~3W`RkEQ!3NvHjru7t z7S!uG85p!Lqy#E*C~h2C(LwoTO!aoD!&G%j2s(2&A_sJzu@?qCX72Zyd+6T`E;t&z z_!JlhE;<>q^i1fov-%mn{M>|<7a~?&jKT!hh@#hCjaqwk(%S0?+)&K=Ta(w_)bIMA z{1UtVPQu0y;y1h>xBf2Ar22a)n?FJsjSrL_W;Al>{vCi4d~SOVgJnBjl<)esZ0C#W z{jaO`zn*^RCp7cWFS8E+$`ka^!c+fUaPmJq7oPf`g(v@K-qF7SaPE=+$n)^u2omQU z{&V)BKV~2PbJn3hW*z(!%|7_|tS-^CJ%4H|d7;d#c!Z|GuVY@mXQEfSzUOJ4Pi!=#BTzDij3H6$W3L~N0^KAXQ>z+eGC zd?pu48L;7IJ}nHvaBTjyvH91zN=l8ClTd6tvH6SW9u7@BHG+C+(iwbkXyWN1@h2S; zPTIvXPQz3iTfhhVO<=fmPaoz>>DLFV_5=k|(m<^6og0$+>EII*p>M014~kK$KanST ztT5bH7~}9k6@tpBHuUiXy;&+B1VG%7_Zfy8FA7QiB#nDKQH{{RAR1L}IF%YB3zTp} zK8U8up=5&E0R_MyDSqnur}jY|j)Eb{pdGU`#G*m69dCsT1~rC+qxKAPTe=lEqyCe` zqD-vujR}RJJNBnA)DEZt6b2a(Iy9bVqzIHh%DW&7yrPGPXB(`^Ra z?QxyH%X9AjakKXD^qOuyG`yENCw9Yah_i}+#@D?Uv;KBM{Rgq@-b<{%m$d04 zl)B}f0 zjDMk-2hiU$_y1?czW+|${ddhS4DqkZZT~6n__M72kAg-%9{QuYO8P2SZn9B3r=^LXjLt%z^2F0nX&-l-4Mdjl`%h#ASoZPzj^EcO zd@nMBwo#nvAwzD=j?$-~M^Esnyw9)M2;iN@J)0CnsybLD7FD$xA7;6i8RHfjZiswP zS48y_6P#(9APfSah(AqN{y0Z<4D|pTn@y!sG96VWB#ImI{g-%4CK&N=2Jykcff9=f zhN>)sAp)T3gD}YLdOeE9&9rf*4+5QzNcD?0M@Lo&nOI|sP%$``c^Ji@22h)zv;~y| z0-%+_3D8$;@Px$3VtGO$7*3)s$Q893Ba+j;HAeJQiB4l@8F5%47|zuWsGn8

j}B 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

|+aPn*Z#t7zK8s6w$B(0H4HB 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%0AZ0{?Li#zv$b;yJiYJUkcw@!LeSFOGPKZ~^$N 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%0D=GCGpB${+UMh4HWDL%*ad&v6wtEhnwrHM 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≪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 z

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 z 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

)R?b^dZN7= z{FV5BXiu$>2+s*(MOKO_#H%gG>7ms4uNMErPY{0gHdaSE0B}^o7tR-NH?Ro7PbgaO zw`cPUo}bWsGnTCJD$rvb-Yl}<3PkbG2rwAFO#b@Kx}aGfwpNGj zNI)xn77pPHSmWh0(6-ZM3#J!@H@9U^NDU01Yu^|q&k{fB$VknmgA?cpadGJT==i^7u@}e8=pUFY~|BYv8g-Pcc~mxQ(?7 zeF|3vV}raZ9tUkdD#|RMvnbJ0n(orCjvZ6>3<_57Dd&qu3cx#vTtF!Z^aMA`gm0$X zM#(ChCD}ggspjQ@mhdj+cO9k$RLsjl+xstvjeP+fs7o z+Nw8ZPT$)ee6*Vtvu8wVFyuki&%$>|WZA?N#OGOh0X2SdOH!uEqAl0a(QH?=FQ2f&rKG-;>`o%J}@CG z(dnl^iXc#wqPLXXK^2W!9-}jA_+znRT863jub|~V9@8I;l(R%QKh-+;{wC1e0HWPnlHC=*=(#Uc5Q zGfct~2T^zspLoH62=N>85kegf!Sh+iEI|^F{c4C{1^*G4RHh5%LN(BAGJ8(Zh>DUp z&oaulSrADh;4WoV>xANi(?$GDUk0>Q8qtBkBfX~4Bkloi1A)@3 z(oRwxse@y1B8V=8pAA}AdPt3$71xh4>if}?v3GBCoufhGR8R&3m_tP&2kO1IYdIIv zt@Y5q*w)35Zv5j1L+?H8dw6@`!L|PT@ATezr|F! zwC#ASmPWy#@F5(zcNO=!N;V*e?Akf1M9kdmh+s$V?zUYzo4?R_YR;MwH6D*@j>k(5 z2J`u$Vy%lU_JbeX9(;6r^uevB3t>FgaIQn=kBwW)IXC`nG}nwd!&1TI612-w4jg`T z^8)}%1oMihl@AD4PrwI|8J4+}#G9*^2ha>t`5RXI899{fAeV;(f4Uwu{&NCRBR~^K z3lPwY5on?jmr)cxlaJT_?Em}s|Ml6={_V5>asOZcQ};)kZRcm2cNkLcH!t;==3CiN zUzv2!K|se-?!HxjaxW^NTJeSZob8~*d~xiNnEx{VfA)u$8y=tk@FE4Mo^t9v3Hx}# z;SPty^gv%e3PT!R>VGx<1NGy{BbdLx0Zdq!L1pq6PX_J-37b7$lH)1^MF*y4q#f3k z)SyqCCi2&AjI;hs4gP%T5OxyqIn=UWZ9;{ zUF?V}aD-sPJNg!2nal}M3DO5qOw!i?ER#N%XUvW_^1S(}7J?)(!Ek2GaWU9^cj;iX z>ecCDbSx;5Fk!=BfygfqF1a{_01Q73)ruKEjcV9-NCDNyhVeQQE*x%Vz}oXTNzn_c z&&$ILf*Gj2fy&Xxo3_nx&5pnRf`9Y(-j9Fd&WW&t)h%G)d!|H1PnZS!Qs@=IOcpjF1lPYmda_6Ld(mlE@N zUpS;mg7a&z+F&w{`8Z)QW{NQR$qMVSJ|Ienuml0ElBf8AHiQvlngWnRDs9ltqX7+O z)W-v*Y`0-lkS!<0@fK`tWT${%d(5w6Mv2ghp3}6^U%TzMYy@(mc8u|{DP!lacB=!~ z66`JV2Bh+ML~wbx?`}X&$-W7`1%XNclcL#Hpc2Mu%jYD>Q$@)83TktLg;~B5p;TlN z%>;|e_%P8DMwL~zWY6|H7e;>VLBnpEKuU8#9%QEvshkdF=+-qhBg1Z^X332;nwKZK zZ*5L}@^I{vMA!ht_`~}{kMH*1dZ%V%3~di(qg!j#Z^g`K+{!o@+mPE0tfR%1Zr+KZXxV1t z=Rs_gT`&UpQ|hZ5TkMDbXXgj*Mwiy<$*@=^9(qsbGY*5T!rg!=~q49(ACoylN3+{;pBtgoiW*Nnroxl zN2|$17(_t1yNcjXY-f!Nf`7sPy=KrMU>_rH((yJNo@o%kmQf3c`W-p?WF^ZY_2DM^ zf^w{e6>}k3r=>V+5r-+~2vFhzy*hxi6M{6*l7cxKm$!T)yqNiDD4s=BGiwA36;N8b zGx;2u>4UH5XPSLPl|*2i6JXg`sz_^314tjiodxj6#D;Eyr88lyKV+viiJp)S)&amv z{0IDDo~Sh11;$S0c6g#x(OYT`xo9zT=z_#M5fnXQq4Ed5-j6gr(R%IAehaA^ndroX zWCwx7{U*E|c~XKZS|A`1nL?8LS5>V~f_b9KVCt5!qc;I1W(?digeCExQ7oVAroniP zry%K|*cWRHgh>cU!c8;3cBSXeR>j(I@oEc2Ai7FaJs`mFqz#v5-*8JF!G#{T1dJ(= z8(|iKET6GivH(dI+=H{tiDGa7F+b%WXAD*vv|Q0vX|oWSF!Lp737$e)JTu90hax8b zHy(D~y5j!$>BGPJgSM+-`^Hqyop~ID-k2;V#sY&7V~LR5s$zb|qi{bEX2i?lm15*Z zK+xbwI8WAJnBXL5fmg5re6_t`xh*GMPo+n+hb*RFAPnZsnULAgvYF419dp;c=Bs!e zLOfsv2qMx#hJr;Psp9ma;V1Z`cp)I8v;mdEfuCyz<4tH>gr+PSRy0VCqSYp-(!BYG zj5!N4T+kEbELuNc8CZ2G_GIXQxhi}nWtbP29`>rh{IZ^y_z(UAqfPujI8y>d!#Eqg zkIYBU@YFO%}Km`cWt+fr_zT9`~Y}0PMAkxS+#-$4hF04n)RGMx+ z>@C1N3V<{(DoJ7D-TR|YZ`7Ylvn*J<(8?(N(WwF{U;;Mistj*weymDX;>t46n#!o1 z7QmDos)+TP&$}l+enk8iOWt?`^)t@QT!-~nf^2!?Er`up%E3nl`D<7jZQWfQfA5y( zOO*PLSyI{d&N4cX%6Nxtkx;BSxg`yWZT{tS@6DaoODm_Zt(C=k>(7J%`J13#95_hSZu%N`<{+0zM(WHdDINAwu{qrpnyo|DrX*S;R3hvoA)E{?F?Lvv67OV zCN(Rhl{U*lD@YN3cdSJ-TyNafCoAswhZRvmk6j>yL08?9K&phxJp7f8qYH`j51-?FD6~>ex?h&)}8d z>g?ZP`om)sbqcmWGe!b6icLoQg+Z9Cg5fQ3>51E{@uIxv2W7plgV;_Zz<3wA05E}1 z(7M!z?1xz}h*~On`i1IbD<1w7LKM<4zeO$^O#%8(+~kB-_Uc6#;}&z^;}az`0wRD3 zuz!ITNefVu8)Xv203VkLj0`=h$UD(&1FfL#2kIeY5%x2E>@*SkeIhmoPe%#Fqj3m# zp!{A~VE$YzKoK;;{zDxK1jOeEjwIlZV)dY38bwgY21ZIF>TSO17)ugc&Ajce59eId9IA0x#5~`@rRF_Z_X9Z503g*PS&-ge~^CkfGXlP2U$LC1pyy$3^suSRU}0t?g6wF44~nw#*vq5%v)$=7)|Dm(J9Ro5%ak!$d#gE z@{5fUFQDmiWaQn;*^vfW93W=VrGQZfyd{S?K(_)KRGQ9^s;3ZKcIRHMOq8uVsU1ESI#XFi<2ZuuWO~Fje#8%h3G)0Ti_uv{9a4hx}|1{v=EgxsH ze7Ohp5xEA(E&35i3WS%~NuljDuS~aJ-I)5|(ZthR4HxE0!5L;7sK&8AKzmb6+Zz-Q zQq0+O$v(tF5V&Emt4;Cll+VqG?XRrpN%kVQm%+OSqi{_153?5SAPg2 zP_bwuyep0ndmF^q8ErpVK#l+EP#CwL-46d*nJ8*f5s|9#pV2Ui|AwO(gC)d&f3%e#N2CQ@!S7FLwRJ|5KwHkWW|uAexh-B_RKl?#6gGVA08O@w6xS7fw~f z|BBRewjN#>w@(vm!WR0`|L_}rk8lW;kq-8DWr(?Kj{0qP{f4Vnb`IV6(xl&tM@6J ziT@b>i2jG{;1(wtI(@#>5DaTDO0_Et&BclALNzAVN4Ly z3t;uI2e*fy?yZpSP{c^q0O~QG8)ZB*H|@+{ZOB_{G@tWLeR7=*P3$XYMqmlicKCv2l_f{2)~0Z<7hz1ek}$~5zPAF!RK>)9 z0H5PNiP8c%V~^}B^?&Iyaqlf(9>LbWIdtt`eLMZ#PaKzLSp*E1L1^W#P~am&#ntES z$>ROfMQ{gv3Lsj@Q@ifYv7$?S6<8cOUC8`0pB=?Nv<2^im$5HUjuf9^+hY*}2hcHl zxF8Wg$+8npG@^y+x00OmDtx8@ct^ZQBs2ml2ALf$An6>6Xpcp!)u@;mt3EYnK)(vjO(tTyF|YPG zNr6lhG1pxT=r<;E61L*SM#Ji4-S#Y~wSB|O;1cX4Qwj8{uudF+&$%uuE8}zhWsF** zVwFW04DRuJrR@dD;j9Wsg}5aOk0X0hkc^U;PK7PzO*g$y`C13--AhspMf0s?%RLqA zy@z~-wcBp+RbzStWQp>Cs)^aIidYp631y+WqKL!3KE`IW=66<@=R(yF+=rznCK4Hu zG9KsDoa0#1bYk8BEz1{y97KfIMeUWbM$?)b{2#56b1RDY9|RtL8J3wtO_UO_Wfk*>qw5lcxd<8TBrr6<_lNPmr=IXNyn zT3woOP`Yc9ZJ8krnx)PQ%eJ+t+Vx4t+6>#M2{@qi*h*BVd(E4}y5(*xrZJ9V_?pHa z*$+Idec7#F>|xh~F2y#1QSvfgQsv1OUK>52suz+*;KiY21mcElio{hF+<@5xeWI)N zoa^*EUbtY`lk!A8nU{wZ^<%n6$0C@e9!7x8E1gxVUFL<(8kSCC*%385t`7en_Pxaa zH*1f{mPXm?a(GX}!T)9ar_NWG!oS=LuTsErtMCOchXuZXQ$)j2s(QqJaI92uP(P>* zL4J@{DxMDmmW3gPzo_|9(=j7kA$oEL}Y!INcHtx(9oMBit z>f(DqH$k6BqL(S8pdOzDw#Oa@QedN#PudXB7(xDh05z2dJVvM`)WVPpjIyE?Kj5ln z3!WH6^IVEMC|(c>jI5y=WPdvNe_pZ!O9x0*+6q7(UKO#Ien%b_ENDi%KWNc9n&@R9OyBh7fyMxjP)-Z< z;V#FijOGgnZu0%5!e9p-iinFm+JPrPVMF9!7zE-u@CDT`0A0_$2~}o(PzlMu4QlM8GjNyv*v^|Ckfe=f(}r3w|Q-$%G|0 z%{oXIdwHC@LG4DHxEIbE7%9afh8RvwLfFLZK}cjDhPS%HK&2>DA#OtDIP5V&$sOc3 z=n#Uy)CyC{BrhWmL9=mXoaOaACiQ>GQYUOFBH{d{TGq1U%{MVy!SricoW8@TnRgoI z2bkK<^p_%T*U&`ZZW^^g!(ro-8@J*A-*oMA(Nc?PbtFF_CTuwi4(u;Zur@kYOJjl& zkS0=75vkEe&=$7ZR%b^ZU1{5$W3HqmD%0X1?dYihQb3kK8d*I+fgxYLaFuawxcAnL zkteq-TQe=^;tl6#yRKiraTIkZ2$e3~Sa&XhptSe?g^HCis;tAo(#%jL`bnf6;`yem zkCAN1gm2hd9Bu7*C)IIvrTO~2?R=O*4V*Mny1U`b zba~RDopcws5wg)Ex&3x^!eKT zubPkUtvme1+GB4zPkg>^|MN;7@Q3+dMbiI|p5L#DBE?$iijRSBd`wWaK4CDHsZn!amU<;Ed1A zkQX-o9LV(>`7UfuBibbXbJT52Fy!T2nKaG!kow_?NEX<2N`)VwA8h28HJHgWiJxc& z4kh~_`(&VuKSXfC#enV(*oROL=75$47zeEyFccL&#A^Xe873Zzj1&5R^dux2LV6km zCH~VXsPUhIp8zf`z*H&8f?9}L4qgn(RVJj|s?ReD9Pw%s#~azwSRqA}k7W}Uieb`+ zH2BQ;P)sTw{)$vXjACdUMD0IKQ7yu9iX~pEq!L9e%Ia`za}JV5{WUNMi1(;nkqQf1&%7&o1?RUp*eQ!7{vp*gjCBSs2WYv_pVW7$1^$sR|TG zhSA&wC~04xDkh;Y;)I>DxYkqIB37BwjXqrAL>_ZjRZn?@e&@up65p`)g*#8R!!*NvE1xfK=d)8OF z(s3+ad0IkEZU9;8N4P_&8M4DE< z6e3$fJHfo33m<+KTN}mGKBQ;DLi)I1c}BQAH$|7xOxQ19=_a`Gf*GOGBzmgWMmR;F zXK(}{>VO+;gxAFDnabqL%Ps)ss%X{On^UtiKKW!9ItCpVgmvjk6H0^JR6Q^qbrD}f zieYV{w<_9Om25RG_jO-A!{T6ADn4jRXbL=pXKJ+MW97R>N5JS7gdKRker2ft_RZmk zcjy`#c7jc35@QeVOgw#De=z~=LK>n6sk<1Z=BJXELETwBz&?rv;p`#!wUd3C;OVF-2@*&$y#UI~jVh2K{;#WQ`TovYX4_nT~G z#1-v&&u;YIpZxY8KKrl#;@Qu?^WXmJ%kEQK_tVdU$}9cKUhzPY)2`f&Cfvf`R4EG>|AyJo$QcuTXu zMgZr!;6j+Avc3vw942M}HQZAF^P#XVfj*a+O~3&NVup8kc_$~>VI;G?g5IOR$Nh#n z*;PWorybzG#F>Zofu-;PLusmx#7)>2*?E9X-^hMIU!QwE5Jo8S;d!AosT}y$(6vDg z6aT3p-^MT#;kvjtpku@cNLeC}d(V`H{bHhwRgBt52hb3_BdAF8BuV zGiNL;x6Pb&peZ7rzb&G7?S8KvLODO)VBDJF*-r%Qnw5^ih4!MAhJxkV!sVv&jnh?U zM~m0`aKG8(DLU%0WQVaXpDa!eupoeKlKX>&U?%>r+&vi7@AXx`6)cBlZNA1Hv3BH< zEM(-Lq<}r1+`WNZp7EH!4zP>uT9~A<2}N=-%n0}ry7Y8c&O$AR#m0pjHKloq+!Oa@@TMGN4=;_q&JcxY#?&Q-;qYqa5ZZ6#a^Y3#KNHk(kO&0(% zga4{}FdrSvLye3zjn??>S5_7OK&&4|d#U9H~vF|G4DX9pJ4*BwxN%&-fLVn4SEjQC{fQ%i879R*#l&_35UJF%i^EV6@yPWERy9ia0)fqOMfDL3S%^VIj-nl-XL@nc}bQxRM%va$dVW4AW7%&{na~ zRld-{rvodRHD$zZ)R^v{dVC$+l3Yo3#99H`F^G>7o+ABxuVr!EnjWJ=$KtgpV8`4Q z*BwHEbJOSCPCC!}nlB`pFD!OmUp{>=1wnJdU!z~^op|>;ZlVJ>E?_h<`sg}4=po3U zC;0dXEOaYi=@8lFY?xYX=Pf{svy&a5xMpqC^}((Fd*_i{BK`-!AGmdijWck^Kw)T; zXxqzD*d{cH-CVF7Eh{1=cxq`Y!e)ZG#B&x-g=hz=i)Pg+UCdIdbK~fWnH*sWY%@b) zBafGXkqPYlAs81$JM=-_X2`h}?zob~FJj={PW=V(BVsdxuqpuyXG1&RTX$i`v^7?~ z)Q6orEfrJJkb_`573o$!XgU$Zr4Sq_+_Wht1JOV|Xg*iJ@!*qx_s2i{*-yX!?8i6% zhEsn7E?f$SfjH_PGIYmbu%kdnUHa!L$@QEj35VXns`#XluFuzy9kRUhv$CdBy% zZ4dY%8{P@9j6fpM$rvqyAm##at`9Rdg>VQKpnlEe+?pZO6Zz|zB3bTl+#HqZ=FRcC zP1*rB?Er>9Op8OQ)2M1=&IZKHig8fa z7*8apv}PEperJSTr3~`Gl0#zWdwV*Hff&XVdO2&osW1WHjJlRD;dJTVDO187;+m$^1Y@ zxCvMP{A5Eec=&=NZ_z2R(qb!JiRDaa?FU~SetHINl77hz2#@*m>#j0p0dQSop=8!< z-Nc8N5M(0V-ybMp38UxJ>jRI^m66aBwydNzBW5Cw!37-k*-BD_x$!pkQ3^HeDdMGq zZef*)_!C1men#b(Ju8#WXfMGJsb(<)!T3mm614tI6`v`itfX%|%~-p6oZXbsR^D3M zJE@vAPwSP{tXMtjQx1{+z(FWPhET4uJ4`lxh&RQQ250-4&Efr17^49UmV;vejLiM! zhhP4iAB{a-wVofNwm%pK0;=F{HLK$#bFEkaAZ)fHO~@uv6wFd*K;8WVIh#ESc){ zR~~Z}R;5PUcIUz2>({&}pNk_VA{&rhMZAVkK)fxF0%cEImp!%X9?SX&Zwh_^M3h`s zzndDmf0f{W`pyP>jR8*C;K25Ia7Z##Zot-mciY1V!25S;xJu&A`c02MF?f7Z&%7-= z$beZWs;SS7>CvuhYpqw42y%!Rl-Ydxg^VlWWTK33qe!7bK)Hdjn|KNV=7g*=#UR_A zaC}lMszj}7$d2i7ASC`zJiO?7?|jwb5G4oVB9bXVzI`{^dvm?{QUrFp{hj#c?|&Nq z=3{J#NUWG0u`&_{xiVc_l*Dn`4EBiZwlLX>(*-grq^i{`edXc~;b2CL7y_xGnX@wC zYe{#VzT{7RdgJN;^TU7k?596`_LKMj@`rO@yK(wzyzz_&6v(>LM~SOTH0Y9b+E{J& zqKQiKm72F+sXamH#;#2^_9~HI4gT`8;sqhm{)H}xAJi0}wg9i$juQO8U_L-!@OkTj zL#Oj7-6^7E;se7IuZ{Sxjkclu0eHvojTV5pT|E4WQD8pAf8sVM5N#0<4P6W#Q~ZXh zE<>!#u{^=>ARBub87P`&o=bKLCH_c40TJ4Me1N(JAG=J!D=T4FC~fQ=kXum zgja^;nYPZHtdv<)rT%By3oJyhL&^?%%<_k2t+Ms zgGW4e5D(-l9!gJl^v;FZhW3{1`*@KzIM$pzx!$&%R_9Y5zqI*IU% zj{(tuZ=47jjt1HvF(1D%4jS{?)56ov7&>Q(O{zm2f@re6#;5p#0h;1uYgplJC}h{*(G z9)~MI2F&qFav|a>MZJS}Q0hB(>dyygh`e9f&7_&~=Yw)oq&v*3Kmkaq(C{!PSj^vY z?P2D?Xd55~&8Z}M+1tV>cO```hoJPzK_H?+Ab(N2^0EohT#9f>h;I=|p1!gJrj4zA z^}+~brD5eXdqrhQL8ubN)GISNc;E3Z=vx75cp0YkQHUp|;TVHDF=sp!E-hMaYPcM2 zxEN)}nQ3j9QipfPR1v|GWiBljlT+_MWOTRf+EQVph4ph>{ET&+@@Z(JhMrtHedAhQ zr17MuNE{b2Fq~lkM~W7*gKaz7_ux|R-79@J&)07S*;)>(iv^r84nciYoV9U;Vp*bx zk1<*j!@JYj! zHK29t>IfSF06^FXNuuFl5eQYr*kWUcrNtV8K`mW^9R%ZO`{8i$6(`h#`N;C(h=ujR zcxkGlAnG>`q&PtIXmx1n^CMz>1TW0lpc8MokZ8Z0?6|Pm0mZyJg<{sU)yh~wG?VS;{BvKv{^-ws?|1+HufPBE|MzP@`O(^Uo($bix19IaZBMeW04^BU zQ1-&phLFd#yKM&@8NXsX^sDB5v;cd|&kKGv3lQOn{LgECbzjU2=jWFx0PdK|U)lub zh-(k4ehUcciMLR|(gpaPrGbW*%FmiaAD*0G`)v3tzqnp7lne%1H%kPxmZ@L+~ApXmo zg|}Mgu~N>VF00!bVVaB~Us3>iEkOkNfX#t>+ z5)Qa3zQ4qOQpTZ)BADOjEr25IK@AS9MAs}``Hbv*;UGS9>2i6H3qWh30EpXwEew5- zXkgq3M5F`uwqTV{3P76&wkc!#UPZkFl_26h+0_m^Afg)OP;qssI0Ma zTzYr`Cnm~Z@x*ijb`=k2f1PdHKmVIgpZ@tjD_QE@KT|CSv0^9!A!+oSCw(w zM@bB>a@5O8lqmCA6y6ebr>lXs4l+AG*M!?Ajlii`*(tomW{qfHfs9anh}A&QKy2iN z0bEd=lWyL0RqXYYf#JM5Rrsnq3yV2?_0zxggn=5k(arz!UTB_~X^-tCHcVnF=~q?2n+CXdV%-a`H(@ud_KfRK`Ftlq<>~Vkv16BT)47 z6#wW>Ng`Be0y?d??RS+ZqNdVAZW+HdtWMBIVZ5VD5Aq@*U-01p7G_y3D|AIMtKjW| z!vMcS$RZm9a`fOmD2^gh=qf{A1b^6ADkzzAK|t$apg@Lyx#edr4<4Z`)MQ>7Q3hKy z5@GPqkFdI>7DWMhhp}QYHH}ok4nrS9B^y>;BvUl8S?Su$lr=N0Kb|aST%u}w@MPS| zlmy|+xG_)?>8wf)(4m{t6Q(6s$Cb6=yI0)r-aw6MSsgbok5{LMnO-E7j6U40*_nnQ zAZ5T70kE*J7+RB)Pp6DU+t>$p$KHM1_rZd`Qe8nAKo%ubQ6JD zNJoRCdT;Vj*jte|fp;iVo$Dc9dG%61HAd%^Wp*VG+}Ub47Xg%Gz6O}RVy>k!+Gd*X zv$GR#@gIKpmp?r7d+$#@-oO!*(wA9a%W5|^I8eZv zq@6~l_R$cbn=LIO0cB&CS&8H-?fWA5i`DasWnro`^d$sD%$L?cF#=^N{N9!mxsy8T zfALTX*wx_Az*psLTXnn(@ec<|9+dwG`%mE~z;1VTZM&rYXURM504R`f$1Wp2&$#>% z?K!}6aCH+Rcy-hcaF^=B5!${yY)ki>lby_ku^NV}1*->E#t^UIe=Q5Ab@3KHS+;DT z_OJAt;dyB*Dx!4=hlDs@n>4TXfm-lILzgb%OhNKN%e7)#!2)6?@mWKu(7tpBK*y|J z1!I2^|BDVy794XG2{c5sR{(J8E}962zoh1Im-2wh!(w$JPLEvnK+vi=8zP@Vwsggv zl!f&8;222piT_CP`7abiB0*6a2Oxc7IFm0x_h8zj01iR&1NBVwf{Kj6XB4DpY+N^)?w+*oIEa)^4H;GfO( z9JY!J9mjk{EF++EIULr$;je(tJ>sP<6@yJyjX-!QWVDuyCbp%)I@6Z_XrKmaH7C}l zTlJ7=h_~V_!Be=vwF()+{o+U&QpS_BWz;jUlVmqI!OG-d^}Y* zW}Dxf(2_xLFh=Ewq@Q5RR2TEni@*Kh;Qu}D>B46`6B2e#6jE8%KoIhU9` zfJGFBn5EK?>uuW;0BD>LxNOur2$>k@%a62bQX}|0PzK~DYH+_XuMHA6L<9E1y@6|z z>_aC@q@pI_P$NH=9D$MVKI1|n8pN4aQ8hqzlerWcl~Kea*{c> z2<%PkDBjy}oN!)DblhHHGI#jhcL(p>!NH6cKx8%%Ds7`wP@>z!l^17VS^K4lSr|hA z$Hp&$?~7rhhlU+|Ot;d>H!Ckzj~Fa3QD2ts0cu0BoSC#`#Ch2^yevqvcr2j0L?*;z zDi}TxvD3NbF)w@AL__<7C!RJvT(ca)H4Zm9*ZYr=28}(rJ8)NKhii9c+3IUub{iH( zm>OV(83sNqhQ=NA^wrJ2>pP)O?gJt*3qT10n2;SY0!$&CK!_!3*c7fxCL~Oy$%e{w zqb}W1HrK)8U~)>$av$RWwyjB$3rpmY1Ca$F1;Eh6{vyP_NE=DqxH`n_F!3LN3)-DT z1NsM<2z3H_hUlf^qCfEAxy5hXO?>U0iTlg#yMg*M6SfUL6z0@gAvMYpHXtlau?R{m z1$)hU968XNj_38i`2VZIP6h#fG5D*a0czyumU&@_12O!mKXRnE07*Y68IaxoPu6`k z*57(9;D!+dalO6J{s zulTii2J@#DMxp*Yu&Vazze8|bTl(RS_~U&^hS=op;(|!1=lo$Z2P=c|CbrL3Z{>Pd z!=x^mqM zcxC&5WO3e}f(SDvYrLY2Rs4;EV`ooxmQ0hVlFKw@z^2eN11onpLh3({FgIz4+eidoIy_YS#JR(%B<@He%zhuqvdZ77)?JL zNtZTzYO(70WQm({TvyrW0|n}pQ9QJa{(MSd@O#>#S9`vr0|f-yr#7lu7HqZ0M_Tsu z{o#Q~hQ$`k!tKDfoV;)|bAdFzKV{*HY9H?4 zL-vup{PiKfzTbZcjnj?wmtBdF{9pAY?xWzI>5y`jINxA%`SoxT*1hKFD1cCO_Qi@5 zHnyH|I(6pSk+B*qAox6TzRiM^!$@pMuwT=dB=uHODJtxMO4>9-X^2$gJI9U*bxMwv zsAUTA!AuJRU;(9Bt^r?bzDB6*p65f6{J6;yp3=gtF#O|}>W<8n;m!V8PXg;U`7g>Z zQkhpW+{Q(q;$G*;xq5g}_6CnBH-c()CT;1u)`qcvWFk4yD|xz--ozK<1!;;1i46TA zl+&-?FDMEyQd_f!b`ZsU0uW@!1pDZ2Rw}R90Dfu#LkRr-Z+7}vKE=JMQXvg{0qOl{ zm@$~iD|aSv>?5~eX3owi>OZgS!!tQ%{{55rM;G!A&8D;ENu94o(>gw1d14`)68NJ! zNpplaIbM6|{(=Lp+GRpc9;-p@fvcNubJj29t+XajHF5wlqL zU?6R_<6LWA+iX_s4iacYXir^rLxkjR=7x2H5)ni^DR4!v~daa0(*lESkDp zvfN_JP(1UO+ghIQHawX2^4mX=6*pB$eL!t-av>PH9-pgXTjVFjpQ>o5+mdqm$(`IO zSuODM0#;xbo^C__LWi|E zz!!$0ejPtjb@6#*{=faLb3@m+PeLW1IgO%|w@BxEK9RS^WKI&qX{HV(ENQ;X5iMK_ zjQa8=C-WJrGSkEVuihOfT^n?uDOkA%#7Lj2MMmQG8Js;Pa20~om;5<^|5RyE(DD3) z$-?yMlJw~^hhX&4?3p@hud>xEO}G169#7~6yz8rXZkl*Gh2||au?+Pwlcz$QP1cih zpH}Sourlt?D-XP1@oDVftNzC-ys93n|3AH9B{m z3=N$IR?j7pSzO(Eh=woOXtkLlrJFdtWe zmz2>Ich(a(~?Q6ta3@Ig=F`@Jc@bR+J}PMVS2 zTJD(%ol&g3los5f?lktu;Vjz^70+Sx5p3LoEHt{J3MX|L=j6 zB3H8bz?--I^qEm8WsVN8i$lXHM+a*FWe3M9G`>ST6C$}(1B@f|{Xod1rHZ2c0n&-a zj6!m}iu5Bcsa`+6F!UQl{Uby1>I2<(_{m0dWaywN+Ps`(DQZK)L;}Z2eiq8QBjZ?< z#zV321qYV$4=2bC~;t*QS0 zl!si-LlHR(r?c0uq%K@E34@hRKbpPt{N9yU_ildsxNdj4Xtlj`Aw+wWt#uYHca^O6 zR0ihcjoS4AcfjTcE0dEb0Ezcs|sbD zP`QgQ?hAaOtvmB{v*p!;wzqJedm33R_A!1ubWDYmDuLBD8(!v|^a3T@-9?+7d8?OG zXX^t{HdRTdoW4|_EO}unD5=vID$My!UrZ1G%hzYW*ggGZGJc}!(z7*5WJPOzx72_sJTfpkE`?!Eq?({i8I0}QF07u1}ZM=`tmpwoA4v}sR zE(IYV#-(zmF?FgQeKcjNI#ba6Y#kO#&SHJeLSx~=`J$Ce#T%Cyr53GR6bB|IAjAPM z37M%%oh-;4EiC%J>(8n_f3J4$FUt47Um2piVileuIOYo!!~bJ{7|V-^^@yKt1QmN- ze*Mjln~w#~$p9(^gZDb~zsoQ8HbuK(d!TNsw_+t+a+&jRcu@b{Oj&`c{~(~auGAR# zqfP?e1q2jKoXr`l7v|_vOa;KP-^V$s4HQ!U?H6(+E7x0%2YQhA zh_z1hMJ0vySFBxUJi-;hE*7px!zFSj;XizSa6kMxum!+-v^UkLAKq?AHJ!;&9n(~( z)!iwf1;BrJK@8+7@80bh8-EaNpu1A0Sg+=$XxEAx5AuP z|FItGt93y%W7l1+Wsn?xUxgA-cCOGc*oJ z6uPx=`4Q*N;-kYEhq}Y!<_2x$DcR|aU#N_mE8vZJaHL>-5B}#rHh(qqerK?u zbN1yWb+j)f%=1x-h(Vnhg_&VLie_*2-XShb$$LkQtc52g3t$C~@9qemoFFmQ-}{^f z(xEhXIKD_*r2DlO+mT4J!*2A|%YC%mj161nba#BV=+Jb&LH*!psaBgXTb#FWL+im> ziCzt4{-!y0xQ({Iewe*_Hh#Re=*}fHd)MBCg;HXHxXHZAyM4zddE%9%iajNkj1-oc zNH@E%R$5)$8~pR^Orh!3^qSrM_47|vs^$< z+P{A(i<6z2yQd>^-NWhXd*eA9R}N0(x()GtRl3;{dYPrKoKIW4L^wt#5m{ zbfR#^nnx2iet6jRUSp?t{~X!doj+7eWX! zwDbo#h3U`Fmxf)i7lmZTm+@7@nxiDxjdCTYhfQnZy z)$Ckve%RA^r_Bj~6J6R=F*CZOb2uJa?M}TxBd~O%V&yt>W*0pLQ&A0R z6!Xmv{ngu@=)S4bO<*oQR{-9?g_yr&Whh_0CKWDJ+MeV?T}eL;>iuxk+#_A7Fq~Ks zrs@qEE?k9)GW9<;neXpPv@clh{45mzFx3yHyBHoF2?zrt2up+?u@9w4hO+|YX|R9@ zeKfV%yBn(lPw5)N@hCBqzvQa58V9fK%HOW}|%9ZMeBW-UU zncKrfBg!vT|9v!7PBo?i1B~PBvDG>@o`~Y~=E*CBcOS+dao78v@<8KNW!o7ZK5& zb#@?(4QG16?CHwHDRp>tME>(h~J8yS1&z<}yca+h~l@xzkp zu33Z*g&pKJG?Cu?ctiX;1wqL!-`YB$t`-nCQOmMJJ*QeV9Olel4KJY)Hla!EM`~^l zGs($cZ3m+r7)@pG%(UUi1S7aIyex9Cl3N`-i;U1GCMqCx-1Zzsvsc<`?@TlE**94F zUjK=|>^b4ry+ax59#((tqe$bExohus#WEs-cK`0p^|#OQwfwBp=bBl@3ErxCFh>MY zw%c9%V5;W+1oM!Z`;+;bHxG^Hh-pY$I*;p)%o9J;K(jz>n6h>{X{BC*&!>|qd&aX< z)>@JlFJ^6CJ^%7{*LT0U`pxqTU*4{NuzHCh=esY?K3l54GY)#nm@WZvKt<(_UsM&FS@?_uJz^1!i|3YksDrIBm+m+LIEf{Fq3?IHYaUSL9XE8*7DWnnFkx0 z^A|B-5p~GBD7iFHUmFb2D*<%xQe3;+PYul@!Wa*TW4^~gAbq*X#pK9Dxz1I7|3>x0 zn>hj;mmBkz8`Ed1Gz-V;07ViA&(vx942b9yq>`o2J1A5EqdeGCXaQOCr?mhMeuzVm zpN2c_?Qf>r-%Qr-UJbR2u5Bu$l;%IZ{sAM1+C#sH!u~(Efd2~Q+5eOO=g&F6rF&yu za5e%CqD}xOyF)HBgJ1PO7`_dM$d7OFPi2 zfUO~#3*V;ftI`^WU(4pNU;(j=!2d_%cPQuZgXHO<_y_Hq%&gfnlK8C5w72TNySxey zFRIvR1EU2~EK?%8-Jv3Bp+2~;Cx7+=Jk3I_G6z*7egzO9q+$VWLUNWBKo>BO`#XWy z*%u_khq_V}XZsfm4*Y!9a46+RM)+%mLDWJ4WUv}wuTe7kus%5S2@NB(09a7eUj^2O zdJ$m!p1X#x z3LNqbRL-~urt>TAT>FRr@}K|yzx>~1BamUAPMc8wtqj0_mD$Mc9Kc%VO8hOfO{Rvb*%kdt890Tq$_E(Cn2k_EIf<&DWd*{$v3^QD{LKjH|n zXM{~nwwte&#F7H__0=ZNw-V~2n?ej?qSX8w)oPFt=-D}@IE4o^O_EHL*oTy2jYe1*OJqtGD6M3wReQVAcULlZqY?jKk zVbhd;clyz)9AqN9;JHe<;JC1G-rAy&Ce2o*FV~u-3s?I~wt5P;+W7y7bYXzwBH#J$ zUB}zEg1Tz&j|#b~xiemIyT4$q6H_aDrPg z-($}5d1fgjRGEuS&adfMU4p@E0r{ZY#Cl_kCD@kPE~wqx1hy1Ao-~6UY<%A40i_Ys)Fb@g2Ff@^ zu<z;El=RWO zUytOPkPnR)lmDy#g8VSI3)apJ{IHzAaKXKj{hH}FG>iTW_1_Ahz=C&=hMQ{de+K!CbL@IuO07zVy~OE{#eU;tp9M^~1gj zTqr*2O$?8ym8j4YnKj1-itx2$ld%%=^r|gU3@u~_Si2x*IF^75(U}O?%@1avPa!s| zKjHnpkU)o_?}; z{>A)-XS1zeFL(d&5T(i)5e;7DJiL_r`9wOW7sXa_2BY~-O{aKJU@p(|fzeWd@~j&| zlEM(nyPzVmHoDxYRPGVT_MyUCh-Q_zGGqU-=@O673#I|rl^_cVWy#BD{Dx4AB~GZ% zSgB*#!hp;V7&sWD*_&-5vCckUPnkLI^OoMe$s3auUfe=O+`Qiuh zyA63Vy-q*^LV+i2IhGDv-=Y829}6~gV)1WM*o1Mo3H9;?8d#`9n9oO^cr%JT=z z))Zu;Z_ZMa=Oj5&?|9**b?*LV_xEqEee)2-9Z-|G)}#!w3_8A?%elf=o4wO?WIQWl zxk25|TD~kJ5=HaUvz^M@gT6wOaPA!U%bD_}5zYYUA{CnhjrS(&?hXr7D%iT3z1Gf3 zlrUMX$XE<U?WKWHw43!H(AbTW~;2Q?vQD#|2;ND2PwpyYGgjBDoQqX{l|&>#yHFJGwKxQgMEIaA5)NBsx>&_3raG~@qYd@^|D`AGFnYwl9L6*zS!91#*1 zOa7bMJ@3~ABha5=pRffWg+}W?dx!sj@sFWEF2%HCpPW4k$q&@%DB+*-%Y*+zl=<0G z!t-bO8Wk`kA4^#+Mfi+C;*cMmUmRmz0uMR$WI%l*} z{l}va2XOXwufD(w0>YEGa2apPjh=O?92U0~Vhx!BfrB(u8rTj|%7kY!jN(Gr#j}o< zvQT!YDqg-Cwt$(7>5+PZO-??CyOaH@8vDy|8xLP+VBE<9<_XZ3oz$I~Jd|txhsl84 z-EGxyjUKAwBU6v!=)&j%e{YnrXMw8$;|}LSEKML%xIdzs_A{9YWuJAhvD{Y`uFoL= zE1Y_jW$$9QQB^v6dI+iU_6~w&0F;*&5I9!<{bgXd;a~Cp!~tT=VXg+|X$3&EhO~IS z*<6h7F(2kbV`V;UpyDY0eL=kiY~jpi-ZlUOe^f&C-=7~CERjT(xzYyj1p#rJ|EM$h z)2=iHP$fS!RagIH0`GDEM2@4abX~)w^hwal-Z9-F-Q9Ule~^{I&$R%(z{flmX%>$n zlf`(+7Q+pKd5+Q~SgHv7Xi(5$8Uuewkx}1=Vt~x9IY3?v`ua+kMSD*LRT1^*0H@aQ zDcg73j#0CNzZV5j114~>@{o+{y-<_q(^8+X_L@t;2UpZ@*q-+ph) z{%9bao8RZ%7s(?=D818`B13JnD~p%HTs6SC{oTW|?RK+Y*=9@QgE3sqBjZKI_gan6 zNHP|LqFWuiAfrs5wzSDU$XhL$#G>slfxoB8BiE$uKEDuDm82+a?2Z3Z%PcdmB- zlh<88eB1K!PS)CGZZpv%LIHY`fJld6odr5=jQ2gpuT&*1ox@g=be6t;+6x#B)!o5M zRFewnz;Y|XwKoHnn=--KpeSX&Fk!KX*LU1K-m~IxXGlY5(!dwzuD3dT|>i6||0o=}hdw%rIe*#c8TzRk;E<2RGg6uGzjJH3siAf0j#L2^Cn#lwYX%%euWERv-Sk{`<}USO29$ z{t5Z{RawCQEd{aruag1h|KV#X?zVs8eAX)dQS#5(nBkA3t!PDrd`p3e8qggxw?P3q z(vcj%e;zx1g?Y2h)$3ulhx2ERH)cfY*hDaekmru}&(ReA13r=?8H^xy`T~b@MZod( zitTopYmUFP*m?vxFbM!KDh$=mxX!Nw^oAjTRUuVx6=6oireci-5ad_K0(15LUNNu9 zpcsRtpM_!@y$FZvE%}cw5Q`}x>2d{7*?=3^9sZhTVMhQ#dzkQjqHq*8o{i+ z1gNJk!znO$`wSGs^>Z1@7Q7oSzrEm{417PP(}DcszBw8mWSF=aR6_oOhwx`e4FL6Ux)4y@{W7=Q#wk)-<;_K3)Ki92^#p z#gDNP`au_PQsBkx1tp!Ov&w%Un!~QzD}x_(XVMyz1OK8UQ9WcP5Qg@_z+Bbx5Gro{ zkAH|J9RxFq;G5JJvf$%}OR!vg*M5IuxYC1MH>eLf3r>tS6y9ocTyV2S4KikvFS+m< zyaS>#c1AqNx-QxieZrAVD%WmCNlidX@7wjlGc9!gR`&Ym2PXNWR z9Sfl93+9ga^)oSDu&HCG7|_weahfU5sG z0+%zC7=(FWOzGXu^tFqQ3#aCp@->2m1-E&roR~3rW_UsljAeEF_;uHJzZHYq^kAL^ zP5fjoN|>ib8V(;+07cqD19}gPE_&_v;pnY@&x8c>hYii+&D%G=+J;kE6`WAcnD z-SSg}QxD~n4`>Z1$I8JYh7cw0sNfqefBk7Xk@{@!&RD*Da;5>eh$ z7aQ*yfO*bZi;{bCF*AOOgITC!pbRn@l+@s2F_I1#N47lsbX)BE&F{W$`}P~lLcz`r z5(#Gem%iFL`(iFm%FZ!dp+-w)bRAZg~b8*$olL(+1MTLWXdrY~1IeZfvWBrrz&0bg>8JBadMv%XHx$bV{+E;hZJe;9@kG1|{hr6B#K=EkQ;-YB3!>`42XzNXWuvxl0r@BRMgGijZW*R_>kOlPo9kJKpge&Xa& z=4z<8GwadL6r4{57JCzzQ@PUV!R;q^>I|Z_hYK>3A67p>@VnJnvD(TfkSI9(=dJGQ z?GDA?rl2VZg~=NZ=`b0%5Cdhw-pA|H^wpONmN^xvu%iX36wWr2tHHvM|GR#}1%Wx9 zuPC;0^lIw=q5gUh*FKYJ+plt$q#1*9U%b4!B|pR z4vd<>{}k7i#l4gNFn3KrjmckVBL&&X$$HKS$0uskTig=JEr^CRfC=*_y@kmOmp&gU z2aklFVtJwG<>AnumA&2>QVR#gh^H9-!^yHYGh^v|>DEBrLZ7cNbS{jeo)84%TgJ>> z{Nr1$yh2ROd*q@F=i^2yv*tyYc8c!xPs09!S=5&k>OWVUfjs6jX{%SrgsBWZ?@y$> z#&+;A{eT#9QoQ0l9vUn{-3g@Jo}$3#;Yy)f^{09gDB%3~w9bPgMbcVJZw(xuXo{Pu zI5<;qYB^NPBeUiECNe%5Ic50&pf@e>h5Akf?by&MSB6i6F=ln~t**KUk?tSv&He3n zgMawu;x`)ww|ZD%2e5rEBYCkJ#Np@(z!z2yjpwdkygin-bTwu6GH7~Ve^D%AAa}D> z(yMq}*SGNP=wdYNOk&6KtemO+6AbD06}LNpGlpkkhXnZ@Yb}MhZk(K|L%i2UxtF+F zdTF(N`{w2kFPdL$NfJ5IoolYfG4T9{$gn{_@x0RQj+h~T>S{B#Qo>@@(Lok!Idrnn z>A-?RT3{$Q5a`Mt0csA)g~}j#FpCPt9W2b~3Aw#sTZ51{LfkNOp@RGsCAuhgHTb-x zE!E)I=x!-XwFFs)bKgSl+7;g>(4IG@zZo|YoskHC1fxs6;hHiKLejOEhTCJ8UVL%$ z+mPgV^}8>wy#A`|$2X4DAbO%FsoaGt9n$KLhrk-K^4(|e&(ai-*4Et_S4GQK$8d5| zmYTx4gzZ05YVk>!64_jk$*66(iiXIcgr198(3O|B&peuC`&@T-rt#i#^YhIsFJ2HJ zxBve2jqkqhCiwdPRoA<3+rIhc`s=6XpKVJSzVzzO*)O-w2^ZTLVMz^9*TuM_G~Au8 zzBAME`rg?WyR78Uy|6UZVK>$wxFFFIg*;tZyw=+Mc=qzM9YF(({_<8XVV;8v3RhYi z@6F&!H9TCX+8qOnHQpU%c6Z_F>h;&Vm!EH)zCR~EOilsY4L69QjjK#2a^@?5QTXQ- zyEiE;0B#NqdWtm@;IEHpvVx2YmoF-AS^xv0i(ihmJe$x^=+ttlz^1Ce6d_7xsw``# z@y{yvs{fcgKevFe0#JcfD*K@Y1gd{D?JN9Y@P*j#YVgbY1A8vVn-*f8Kd|(qA?6P? z__~)KPc|^QC7qsVhQ`y`NlOW!N?+2kfuutn$zb*)-O1X4*1#0bo!9&ytMiZ_B!5xA zwuXjV{2V$&06RbNZ4mELvE0$H6*_{J;aI>k&}G@K5wjT09BV$ouZdU!~Zq8v5qGo<;S=mI53iJ20%5$2G^C;>W>C;4~&(-wEgD&s3<`3mjZ*h zLN?2s0q_D47P(^AK#vbJp@EEOs!LYkcAuFX>~G}WH;{xR188!7CDi5l>@w@p`csz~ z%wiK%vOVrYX-}VbM@g-{!9VBozLKdw{?KrLq;RV{W%)eCQ{rL`QD^%6rNY(ToYkAC zJJtt)44i*Y59L?zLvRkrS?H*~H5GV+NGt;>&K9078&J$2HH54UhiCwztw25UGa9Y% zZQ^|5Mj{#d2%;X-=Wdj5&J}IV$p7!sn6%~Mfyfm{$KT;e7`Fb z^Cvih4kzx%GTrRz`0ev2|L1@I!~gTYPyPM(r(dp=-izel?oL}jAHun28mjO1maKIZ zZePP?{d7DDfG>7L5R8$pU~AAFIUHdpGxOG3X#5Md&zpY3XY5Jx;&G1%VaNSteB>6y0B!VC>%&f5?t z-|`5wZ+(0B@;6VLo-S}~_R?~rFTE`ztRczsGgoW!_q+wctO>lA7ig|v_tV>v%dZ}_ ze)G`Pn79A+AHTZ!+i!1v_fAu2fAh?rcm7s_@Ed=E!gT)GvgpSA^%is>!ZZuWrI!zy zpOJ~Juxlt>x&%YOe^z9&W-bWs5#ZkRc%lAIMD_6JnNA^a8=lyX{u9NrdKqE}2q0Ck zhO|6iuh{CylzTW?o;ulp?a%uTqqY0D&qx01>)zizZT)&33-t8Esn*v!Iu6>E`fqzJ z+w28MBD7~t)(0EU>0-BC`Uod@EU#=$XF?`gsoB-7ncK7W1P&@%ZZ=@Iy_&!JY?d&s zc{J0I^5t0#Rz{&j6A7Z}R_(n!Wp46BU2Q zU%n`cf6`EuD6Vt&W^a78#&1()&YWoUroenV-kTDTpZ?UNy@`OJQ2%=Z@lyTA`El^Y z3`$8_{V0ppJ8JK_m?AfA)^E^%ocw?Hc@Rww@$djVTFOdS|XB7TGo@qz=yDZdDH2wiBRSXhJ`raNO>FaqUs zMK908VJOe7$7JRD7IVT8xo+zR?7KV?3#io|A#b-g_#}t*VN55=7Os&zTNypx<>?^i zd8N-k#8(fkL79aP9%^Ap}$W^%`DnO1kdAUq}+)(cuciJih4u!Q{QY{${BEX^S_b^svb~!4*$RIN_KAktS_(Z-eBF+p@Q{x<}e6#3}H;UDB{`kS6zgQ)`tPh zJ_7E#p;T<5>gTX)NvXOs?@_cp1Tj{Q_Vgxsmbho^>CE!L>a-U5!XP$|8t%?Dw`Pw` z)Cbuw_G1?gd|~|L+1!=xw1u{V0=)Vq-J~7mi#1oDw0Jgq^J?WC;P5E+pjr_Q$33jA zv-kxC@@Js;oHD26#(_zPp2C9l76+-leJP=R_ow(2P;Qus zoFF_Laxl0$B`m?XtSAu=ezLyQ_d65aP#pKMl}-&;)*^`B9&Wfh1mDP+xsWA@o6IH`*gs4KTdZ@hkS>GkvT zU){g{!1TZ-K}#}PitNG20?oB-yIXx`I;!jkXC7HyqdB;pr7PX% zpDa05U;p+?ZlxEVt-}LdK$t*sa`0@oes!n)-E(%uofa6kHS8|1vJ$EUo{;% zbTd7^-|)kfsWy3-U1}X^-p$wd+rHi^TfK>6&vgeQE6S)$R(qKS9O+C9oNaHho+N+H zRn>u5B@gxvTixuWRPw6z8w6Z=6ZQQ3WxJCDXO9L07WNT%M8^IYO^6Dhey7_5jN?(V zebrX$ETR>12yqL@AFZVbPGSuat^dhPYi+Ml_7OuBhl2o@%`qQyluS2JdAEi-%%H>h z36plNDP^YC7D<{Ht^8SZWbEL8|M(BiXGU4+9_DjhAh_{Rb%n%LN_=$FaN!NN*Wm&* zEzvMkJOTIaOVI_a6^;%t4STu|6$QhiY@c4wXATLQI+JRxo3HWdbO#`YaCYwZpdK^- zdszBI*|Fju?AQ9DiM?VR2@23qqZzLU$4YdBkNa{DjF*?~jX1(QWocxHM;5^w2H**(m zi;dlhGuDu@9Jp0K71eGMh$E zi61$0Xdo1&!-JeFV04MG^?_ORz6b~7QaelK!$|$pmEy-^8N0n{Tb;?9tqB`V$Cs!? zi^3gtHq%}E!>-g1dryI4lv5=Und;NQ0xMEDOhq^whA=snqU=dxy-JrX7=?QS4+u`K9Gu1=|I_0FLLq0Z&A`k?-caghiWnwc z9oj=RcJAeN?SqxGU)+-{dGp(EZoGb8xj7<;sz7++xMZ#>X)?`^m)gGlk|>x7xzh|k zLy2R@7D`-*4o?@_Zag`sA1*XKm`1ZV69(g*X&`@rZ%VDe$GZsfj%FA#jAM;^?5Zb3(4$?JnQEO8i9# z95$@Y-~v&);Xj)gL1au-B98jvZIO*%_xyRo9z|Zkk8J_5vX9>H5&OMgW2?cRe%=4c z#S>`Ze#B9iY~W8->e%VV+e7Vd9$x%%sc7kn;-5uAViN97SL%}o@`Dn#D|q9?^|4S+ z1~%#)>c1I2R{U)Zf#JCotbUlkA%C)i$Q!MU<-7|E6CbAd2ZCr+BM_s5+H{JSTl3d1 zxV>6}7*K2UDonhKPI;1!7N=Phvogu`?Q%ql^2Q8UAJxHl!p4MMU&F#9#M*g+^XPeh9B`-Vf+-oPJ9dh`T<;Nkbs z694JrJWcyYyCRmD(ygQ2XO_Ue&R=D zXs^6GZT_#myO6gw;NSY%bO!*1BKd1a=U&Mp1%XdBk{3U9rtaRNmJ!aEBSHM-*nx~x zv^7$`wU{)2IgH$Rs>0TX=%)g8(~4p8^bzodv{#MWR`p3oHn1hc!COF>nvUnVlZr}A zTsc?xpug$my2t4kYuW+40>#luS8@{}8|yZn7=FHSCi(GN-?9eHfD~CM1nHWT=0XMY z(ahoR^`Df?2=8(BEPsUGJb1Lo*)!dC#+#ajgnU)t!itD_Ksb$Hky3<>JtE=YjphjaRf&3``Cz%4x zlnUofTRoGr+Db$KL&eRf%q4AuYsn*NraB2OTo~-o$ z;hWCyUtD-{yLw~P2JO1U7ijRGe8W~+&R6!vSz}nyYUi0p%N^f6?|App9mg({JzkzS zfiWJ9{hB*lzA=oX+VcEX!RC#lWYM6c#p<}l(j!Z`y1>Cm>7ht@;!HF9ZflF>sCe#r z_VjreLhQz!h3L3)5j8Yn%F!wx8iRqEKHtbVC2gTbpcoY}KI+M_GEER26v$wqXnD0( zd9OQhKHLf&O0cA&!rod}6}C%Sp5z5uJpTWUkH&1=&hF%9DN~IZ{^mq6^M~Zg5;t_X zTp$9C7odQupKL$X|56I#`LhK}7n}q9o&`kZR!hNRsQ=E*ne$a{7GMWNl%M?{ewzF_ zLX__bA@6^(`i%YN=XUV%#W=1zf%!@H6&^MDb62jtSQ`BOmrV~Ra!m`9wK)H*e%uIn zH$h+sensz<1#WT(M6O9-_mI8z# zq#bu*5K#G|fXHC!3CZyhnC2z(9bynPbEa(Ja^`rTxiVcbY6dY^5Al9_VD-3mv1pb6 z6&2(<5c}TopS=h1tKAM%X-qAgQV$T23LKV#(Hv7BKYz`_u=;6tDhEX~K+s>z*1Mx& zStuiZf{SBjw@sM#s}o#{G;P6;DrpIdwevaBQ_E@8M-gYX&6Djs1I!NBav zVKNL!u!mom4PsP-q7ZlJ+L!yFa!@Q9|2DPJMD+@2!CJ$Nq{6>be4 z9w>JaP)W?R=6^U3!VFZ$s2t!O$@RlU@Jzyl13jLQe6`eYuFb)v6Bo`Y0`Qs7N7LRP zNivor-slTQC#%TzGv;sRt@p)ERXbi#d$}x!;WIG*leL3_jUmjs>fQOuo!P2;)5;oR zjQcfqiVq$z3V~TB?cTi50)`4tjMc)pRM%e(9{-EpIFZB*B4`9MS8p(yKoB*Y`&X6% zAdlxkQ18Az!?2@6aQNKYu?Q|*dA8|gx10-Vwlgts!&NvlFaBKKx> za>5>$`|(KP`~C5O+|`qBl?bx&;UcD{a3o6v@~4*p!!EyCC}@hq>AWY=m4wj^{?#eg zsT!S9>QbX1fqTT z)`+s-???h?LG4Vx7EE7HxZsR<+6#`)U+PzZ!sM}!4QK9@+f8&F3+<5B)GY80$ z;;$`2dK0J4sI=^K_};Yt__FfB1ih_UJ!`EQUkeG!edOSDaqzN^V1!;_bWq{Sxit_v z<3hC||I}=i`+`I&`$gTOiK8I>`I@xlbA)EJZ!(2b7h4@-j*XtiKt|5rH=Mj@FmZ2Z zNK7z9flN*K8H<+?`>hG$8_Mr=>J(;OVrt1ICF`C1Ld&#(ouS(85yn3G{2%6?ets)t&eK^ zJL?4{SQZe9lxUYk5-m|vOgs{2%E%BrMK(cZ9YF&gDGO1Lk>c!yI=h3$!7;;6!FQUw zdhY7Ci(XE+wP}mh?!3WK%7K2O5=!QjKv|qJS%7zxJ>3ZTH}jXQ@&CDyy>K>Mfft$y z#PI(cZr^CUi}zTUH5)us;YEp)CCN*b|25k4(-sgt`~F=2W2DeOMT70zb2T2T2jP?2 zD^~wyI$wM|+xE>mBtLtqDPz1gce24lN~1J4lmE%Cg8b>zfFSd~`!54Yf5$u@tNDIa z*wypce`5Y{eiH=70wSa$O2ft#3&!{zo z`!ePX6U%UG9;8bO+X2+5V5=W0;!l9j!Sc5+*YDL*h>&R+Uz8(_PY2+In#NRSpLK;< z%b8n!sJJ(=Z!F7f94Lju#9}8u;oj2|_(&vCrQ4$okC&-sKl_v6v#u9_qXC7n*d$qd zYq5HJzGip1^3jlm<-?%_;;;9HP8j1q=uYq*8Cg$^R#NX$_=2E6qWJ|%cPFq%fGMTU zUpg^SulpS6aV06TUa5rPh>RB73r8wYR8b;r9EV1##GD~LeiljKGfArp&T=+&U{#O} zx;`L5F=vTz8bB68SRG)(kPo-5%{Ot?!KqqfKD|hP(9+wC< zgs#+OW(W-q1S%UHbk6p91ECdV=>mUxZxcwQ>MV%{PrMA zy7H|7WxV0Ra?7hnoxgp{JE-R2bn?=i~kdYfWSVnb-)S` zJO1MQ<9`P7e^dg1{25GW$$kf`qE_l~p7Pwui{*=*C3DxLJ!191>eXb^xRl2Do@^)( zc4+=gvkNTn$MF|-gyds}2jj$w|9@To8UE-6)O@&G2%l9{9zR`*+qeU9ih~Un&!4L> zv25KC>_|Icd92-m2VM`x8j*TUHt@08=|q!o&0XgFK-Y<)^lY3F{!fhw?aD{vIoO$e zxSMHbFl|$u?JS6JBvdFvah3(v@uZQ8xs2@K&>QR;m^PsOQ?x~`p0nME!|Mm`C$=dP zq+!4!P(QCHcOs4u7Gb~FVqCJ=^@rmTI~r~_Bju#)!YnY)P4C`2PP9h`i_o);E~h3- z!;%8+iLxt0kor(Q0hF5Wq0*Y1!On8beX|fP7gfW&*$?7j{&)Y)S?fj+1+ZvLc!P#p zG$C`QfjNAZA=1=hUjuJU{m5MEX#r>>-h9@RbBvYWX4kJr<3Z5!dDTho5T|C(>>sMw z%TIp1y7BR3&Am~iM4du;x1j_G$XFizMlzSKoBYeSrYm=+ymL=X*Au;}s3z@?hEBk~ z$j#h;X}ga1m!BG{kqCp?ZXNivGavgXTv!H54)qj?xj!)w4qm=C2XqbeP;ZK|iJC$@SOJs zj(swia&r8Vf%D?41*9f>4ZH=DT=g(`Lr(a8X@y~xXis;ZR;zVVTaN%8Cvq9b$?LT^ zMM$KqL0QBkuVA0{P|h+s$P>IZfysNId?W~|xX)!SW zm^BkplffW;wYmIm2eaZcUrsqt0#c4m-ctmV@%O1 zBbqxGo;|+t?gfV;cvseHYw?{ne>pIq=1$9McT$Jvq^?xQPdBD*)M8O)Ze8$dEZXR< zy*ov=pf5Civ83$#Ybk4ufr!OaKO}gbWwXPcg6Es39pZF&DEbUc7a=>T&nK1(k1rL( z&B4-xLlM9*_~uQOY5^=XfmA$sSmhM0x0ed5+8rp_7=rL$dVcrv*ALZdq+jyA;10KR z##REBSB>$06ISZ@6j44J>92nEpj__T;zh)y^N-j2fA`cam88M|aKsN{zM3Xl*YG{s z7tn-+2p{W{#@=4M+*c3Jq04i+9S9yf7*I08umla{bx)?Qee*nF;vy4Kt?N>I3u$Y=oLj27xaj=4ekHOda95(wZqcQq)zb=|T+K%F*o2G_+0_pj2YYpQm- zU}!-GOS9mjF;~w!LbcCXZ1yz-c!~?eq6nMQm!1w!{ms3md!0@I>c1rd4N2N^;p0mZ zUSci4Z(__Jy+HB*$p|9m1rc?A3(1ew2O-#reI+s4e{lXBtue`0ulClU{R?wnxW>ti z5P;WuVlS)zbX^8GBWmZUoRr>VbYg3l@M1Neq$^hcfBseFNB#`lp6$MhwNCJk`vsX; z=~7Fq_-71PrVp3$SJ#73Op6vT`s@~*+=UAn)6D?1qP5G#YuD1Is@4Bc`FoNnybkuK zI6MWTHUxgYB7xrdlO{JzVut^|?BE8><*bKOdejJl(S6hu=vYs#KgafW%kW6($xQP5 z-fX{W1X9|q1Fj74CH6t2H2ziWA8LG|aR879vw0>v(->S`Kb?k2)toALP@EVlGnugU z2-jo{VyFOP@IXI{Z!<;(tQd6@{-dNvOhF?Mt^Ywprm8C}NH51m8;Cb+A1r6A zUd7EezvXS;Oxrl)ZAh7$wtOXLsVy|Dp-gE|m=z?_@j>4U5ZI{rP?_!VWsNmTpqu;st1GSXXl=f|3wIi<|^K?*S3|c z{s*6dK_#MsE^N<8&<^;RRuA_JD}X+wi<3# zD^6H0B>=>w%viguWji91an(N@2YNR=9Id}M8~i9{t1`D5^*G`+nqLb-=JEv`7{ff} z3+6K)Ia=?c?VH>u;^)KcePpWaF!}Io9`&(CNkDx};y{QJC??2qo;JaPZfq+A3rvss zvsG;MVa_x^*%8i*TYq=e zI^*UJJRwv}Sgy%jzpjr{LuYTE@!G)k&0J_rn5e_yZ@4#k`u-%RJH86XMl+ldtp?|A zFXe4su6Quk`Td&Zxg`gP3kQdbtuVktw_2A4kw!V|*E-+6XuP|Mx05hk zQFS|bR#$BF@En7^m_?=cw!OQ%^6&rU>OcN*{_p-K^3UD@j!=de1td%mL1c;XlH>?? zQn!H*BnII`8>w_cy7_LK_Rv*ALg>ujeslSmCuF!}>$+tp*#0k`=bPclaSNb9^Cwvg zjRyYU|F&?JM<^K33Xnb9bmo4KIGDMsOsLq-=lRJH`a<%W$lR1f#j=u$A z^1rAr0NbHG-mtE*%o%w8sF@D*kPu{1ArA6xO4r+JcDe%oA0_sOb1>!aW_!(ApF>97 zcCdrXo4a^&pw$0j_(=%H-NKw%RHA|mC*eOPl^)ML&^to{V4+WK(x5lTwn{oiqfY;$%iAEiQ`S>8xy$k@v~w~HGV%lliqTNA!G3R~K!rDvR@|Fv`SIbIciZ{5#+X8!B6d@7W-Ench2k8z z`k^LAe@zG{gMnoAnE;k&+OegY&Ak%6l_U4!p!;Lr z!LvH5x&^zj1q&c#cLuv!_6`mlGRwqP{-XD!lwr|4%+S&oE^;K^KbLC^u75ld_6wY) zNI8M6N{hYb_3V7W=SMRNT5J~<3J&UtzFhwE8O!zkzx(#u>vwIxdv){2XBFEs@xI`> zYK>3R)Zd+TXip>&I7Gtm-Iv+&qZl2UNLE{@VjJ%-;Mu0FH-p6CAt|fPP$Tm{<7*gK z(Mpe6TDWrsS?kDjR@`ikk3+(YTeW{S>F{FC{+VpZ`O&$8xS5QqJ41+bX86N1WjaE^ z?Y4yJv(XFk&4Tq_YTWFlYmx|*diJDX{Pyp@x$)!Im*3r212I~$jLiIb8@*lMzw7+X z3xyXl=F|=t^dw(;cfak;>%z^O_9Mq)Pn~Qv1l^qRs;u#|S`4habfX7g8{CzbI&_xW zJ2ZVGa>^PXMk;o@jt?|6-Cwx&_EFW{2vtJc>-(qgEO7E+5a+@YPkXW?O~7@y)O3-y zR_(xAxLBJxeg6ETx$=#E>=8$Y_TSwe`Rlj1Ms5uf4RmVGa+SAxYVP&b-JfXtVQb)@ zK5zYMyK1YCtG^cjc!A;njc;~0{_(GvLQsBH?9vIgiv6W-Uio)_kS0tD2dl^1&tN$_ zU0!ngTGq;SrgLdCO(FxhOc!l1!>QHX9;$}}G$ROPAy@dCyX~~V?giq&c*KbT zbvx!zgsPhN{OU(l{5%i+dELSH%RloQk6+d70Rh2$eiHxM0;>1Ri$8jUbeE_q)PIH# zbXW{|YBz_jzF2FxHN=?>yE1d4PMrs*DE@#Bjoyr#|gTj}| zKXlUM%-(oH5#OAdT?J;YJN zzd{!Ua705E#toGnAF4PuTIH4F=#O{&7^#2)fr4EpU8Pk&Xul~P_QluQk=lQnhuwnJ>LbjY zbpc7}+|@z`aq+?K(%hA0CXQ5DCSBb?Y-&wB>HsH!a0Q^b)_k1`+DJ>j_N1FSHHb|{`m|L6|d>No=nsx zJb#3fV?zy}bZ7s%J5xu~M|4IpZ6Khyp(0#&Lpx%s=Qiqzk>QDrGse4m_u|GRAu&pO zL=8PM!OpSJOsoEXIC6rowRXw%B5t6JM>GMlUTL3#$pgWx0JxMsxZ-?#KA(#nC(qia z^EFQva<<#R&H?D2hXR#Au9Q}n-(V=+2Te*9Oy)Q0vyP)6m}ZswQ%e=;YqikYob|?x zl{yXsX7%`mkP(SSh}86p{^OzE_B)dLL5I{K$pS~m(oHGozMSY-p88(=9bY*fEV#_q zR&l>i1NtPAnzUHQ0fSpbi0c|>M^8Ue5KtHL;Zd0aeh?uUNBxK3L6a?OSevY5Ua;dGo9bxa>^}BcNzkAd7 zSHxM*gzVt?ABvO~?{@OOZhf<>{yS%2#ZU)RPh5HZ;M~(~!OGBk4s!b=sTLds->}Wt znUdF~gVql@(^wVrjzFzvi(S1tRC8yj>UO_hNB-*B^xwVHL=5f9vZyZ;5i-9st4W6Z z@E|7*;_;cBlXLkzKU1g6Xu;?vKdLBjk)SrC;Y<-_!< z@87)qdfqMA$}blihcVE)#WZBH0t)MI4yzVZH2nqtCBlx-g z=YMheliGcMR=H1@`=@n>|EywvnE9&%1ylL`@`A&($`?wt5$+?$fkD+tU;Sze`4_$31Z9~^{43UQj47l(?~wu5aBA$#De}zmkim^T!pd^!uODWNUGRy3Ho|BKdGP;5@p|~p zC&O|N^9}jl#U`K70{ZjRe7%MnwwHtly9u=}knM#Vs^lTgCXKa%n&~SH)KddI>_`;y zSgl3?pg?_0q_u!&Q&mPJ9^=Ogr$R^VJ&+c6Q zYWcuKiQL9OeYDgJ6iS)#g`F5HM{vSf!rpPo0elvioZeEDHhc;@LmE?Uu3-G zb>mR`;XvHpKG{sY;r!v)F^X#{(;;tvw-%6U72=koZU9dZz5JaIJ2D`~c%h}c{rNjr zGuAJqtOUbk#(L_!Y2TUHqQN_qOiV_A`cEGLw}%yrc|GPvFkJ!_0T**ZfE56!gUQTd zz{~+4A4f7j7)^O^D20Wx^6tosDxb5`Y!f7X^7Hb>$Bgoce%W_a+vT%*a57t^1+b&^ z@0m;oMx~Q2F9T297s4slg(7tMNP$Lx_)70)Lj-5JMB_M-kQeQ=xC?`!nw~FTd-npM z5&Vd#?VO=;-g=C;RaBX9Nvs<(2SM}J95e}(Ayla1wRQ#e(0JPZD6c6H?;nhaLn__wH5oA8jeq7XDwFZ zy_9e8quadrWCL)7c5?RK+}gkW+b93qf8ct@X9?PtI9GrRTCg0V#D zOwpJiS)F@1t#|v3RwP_#crtZBbpAh&{LlZ#y`y~NTCDyTuQW@I4E28^$d+^OHvf6~ zCm%M%y~psOVy{Gik1O{7vMStvV^~n^93U6+!!t)Y`BQ%J`IK~=JJZtoaw&KAYTN7E zS6{7%sF&$;t{$#h4j;v{7ez73um+*Hs}l2?-f=q>|EOxLB2YtzNHA)6`%r#`+P;Yh z6u3Y?n+QSA4)i4g%A5llZVxyI*bZpTD%LwZ%=wH!dHy>tL!5}sgUAaW(wo8aL5WVA ztl@^IL#fpX6IFo&)1R`xE8R^&m+^^wy7IMFTJ^N4MmxAm3aXehLGZ z@I>RsYODUTxAmJ%ivg8DROl$JC!cqPUBHJ5Q6sVuM{^OI@j&1+ zUTp2(-@WpB18ESs{i9)sN_eRM$ETWdR{F)Y92%{_{PAU|`Gi`BN6N*x_|)pZTZ0V+ z?jr&ktl(Y9A3d4-|YL>%2oFa;ZC%G5yk&7BJNZk zG{e)<_QT!u*>*Z9M5E~8JIUm4gE%q>>CHgjDp(`(yAWANR6Ff)vapOzfypX$l z4d9G?^?p}8i#ceI>iWx`pgxeB;JBdm_*t8^%ovbcKUvE{Fm0F(vE%LnprPRH&uKG~ zFYEcxWaWw3hGSEK)Tdi1BT!16E}H+Cj)5to*>}p9FThsr-IEM3dyr~qt`E*+(8Y=2beFoi|rBw{OfGVx>`wAVYRd3I^9ncf20wXBaKAtxG-+c3h-Ad45fG*vj zM>2u~d0&CN7*@$%crKfe6F;*36B)k#edF0oIPrUZ0jCzKj|E(%%vs7?NdP*mwP5*5 z-h8WGG&N!!6_G?-Ko4gVt)a4IiYgw58B(!{)(+34$t19 zq_TMO4fjV;C3RH+2gf7A--BUDf+=gfl6ya9=E0#9WZJZ~bE<2}Mwh!oILm4Qn}hz7 z{F6zb!U;7AJoCoWLtVvtk^-;cl_ z5Vw6+Py$-)rROVGUu`!%8mGVWLgh8*p2)x_A(BO9V7x>Ms(H{AHH>P`Sm7BJR0DKL zb`7u(3XlkR#h*^LY$NbOX#vXCFJOT>8DpHfcjF_uNCr!15K!soA66ZFpW!DLh}wMw zzcJ6BSlau6Ysp|1r$+UkKVI2Nd&iqw(m8v7cpRAjGiTGr>X>Fz{^rd#mCm(hjnzZZ zk94MEdn*2jofKaDA|Oa`Av7MsUXQ%VCe9E1AN*h2frsCi_DffN*!+JVfMxn`O{iSY`H)gFiTDMKPLDV@OG@)M7-rD;n z3e;qyY&6Ft&%25I(^D$45WCDr){)7?%xU&?^OceXO0`Iu_Kk4%+2do?IPi*z=0Y+Y znBg4rkbHs^Hw{dIXOeg8I@+GE=d-cEV2{@SY_hc=zm)PSkaDs4{9dmmLhj z`qG>>pj)6SOeYZoKBM3O_zV@T9T|2J`0e8*E^!0De=__}pVjRSo}6p^d`vFzDUE=) zTfPvG-SzC1?xUksAr2mNFp_V`7X+hD`i;|3$?EE`_pB468P>Egen>Lt{w2DKzt&y@{v1abVXfuw3J#GF*20TEAame+^$c z5gL6mqaT)#RfZBu+F4lIZ=zlaB_oa8uvwIZjclMf#@p510GyENh;B zaQY{_M%hjGq{07HX<&t;%!4 zGStsb)3KpwTZVr*~csWzyF@}HEaHgu^)TfR6vOn?r|fG zgEDhhT5J%SOV-v|DZ1wT15;Ti=j(*3?}?-xp2-u)Vih`u?L6Pa*VG%(+>3H)ULs@h zrhxKgtX|03I%{&?HoXHrcAC4>vY@3oP)+gftBx9ah* zkVk%}UI`iNEy|!E7%LUJ4s9=CTIKzLqMc4w(pW&gqyLwu`+%|Z%+kXQ7_y)ZjKkb) zc8-;E&efGV=NzlLa?Ux2&Y2y^W@t9aA!l~d&d$tE^sY9@yVmS_7XoBSP_%5wf(-$J zY``*L`8l`70)7;l&FWjX?!Eu{&Uw!pY(0Q8VU#_#U(u!lrjSC&0h{l?Ke_kL1Tk0o z@Ih`8>SyYNK!p13y78fkt=+L&LdfBesddEOaRm6cMf0cP2v}@!aBxMoSZ4*0GP2hL z7EUx1DPZ6uWEPI?WudIGhYls6fZY7~L(VM5eGYWGjLm}~`gZ2x#StbaHW8)N!Ccz7 z4e*Nq2&hQl`u(@Yr9&Qg*rz6VhLU;lJ-nMJQd`Fh$x^(|haXS1e)Cb!?|ruTXFnSH z!{_q&Nbn2}$-TAILku*iiV%J>#&)rqNhHqHn#i0Zl)`FV{CO1qb3o14`HO~U0SEst zpFLK!c)VbuAvIC|VODHli|?O)q3SJA4;1Ltigy4(!S=6T`||E}zAFB&>{<6a^=md< zv=uF&{7UPt#gg5%)N=8YtM1&(&u`kHXZF`6oF8`Q4($sM|KUR@j+%dVg4DZFz!xqz zTxr_em}ilS_7+LLQ>RNOj<51XwedmbT#h4v&p#;v>cT2%lk*bhzc_n!n{`jk)k_tN z=bZ(Zt~z{X8t{CXj{q(v|9JK9T}YF_lE^#_790RgRR`ceSrv9Ouh#*N6bH>hlRqP$ zM~sEzHQeUG1)P(E$seA~-T35T#jv@nh?H;ZK!If_LE`$pOkNF9|NHVpoU6d}R;#sQ zeOJ0pz#Gj$g=1Ip z{eSY{flWQT-tA`iUm|yayCzh}qlGIG0kRcvYtbw1Ayqs2;gr|SnB#Pd^RXvRoVWU< zpQLl&o%+=m;e_8;@J4rm^TO|5d-L*zXLGmz>Sul5e@ZTTIhfb|& zDPhq@b`2Rz8Wf?P1{qVtb_~|-|6~v*6WsgDToJYzB9i$D57csR)(v|1t&PkMZ#Rii z%X#%OSy`x|Z7UFoQRz_llveZFs&{L6LD-Bi*=|XBp>@aav~7Q(ecS6jsoH*ILS>(n z2|Gn%OX;5yc*@V3MG4`rDCy3m9|Qj3%_2t#@sQ#6af?gqXQ+m zdw2QLiJDs%(kJ)4*`54)XY%WPflBfE+ccDIL4Wk={Naygim#t?s8ME-9+Y2eUDKZ~ ze+S-Ws7al!%9t0_bx5WIzI~!G_5`YNApKs%ux12FxYaA|HCKAV>9jYm>RQ{O2Uib2 zxbD2em}07V>hX>0n=Rp_JzQg3s%N&;lh%~Rovdpweu#qa%AY^sQnx*z-HoHUVDT9G zs~v0J(lOLlF=1>dl1GDcb@=0HCuzk3Wql<=6gty};bNH%j_C~pVlnG7rmGQhE_{5C zu6bKeH5;F{Z{0cn$<@;N^Hjat`^xHXc6WU1gQY+DN#74Y(6_T10HzsO2(;-Gut9`l zD)@_k_G5}#4`K^rx6YN_J&TxByl|TN4+0PBxUoW6qvWzgAnD>bnmy70UW@wg8%7#H zPv#CsfQu-ABZT^2d*yU7_->#)@Si>lh5VvNXIA6j|87Op|G&Fy&F@yOeWBq!_5Y;? zr+`1a_tM^Vn;NZ0^J%{5Z56lLmG%oCT{Qxnc|5CEr~Hz-h4qv-cnA~;Ezmm>G*AVSohz%(_2mu@&sZIf(7VWz6 zTz?D9S<@Bu-+c#MHCx$kkQPdjL$e15MSgd0v0fcW0(h|y3?Cb1zZWwE6cZ~>0x|Qr za-DEY&3yAxa_nl`-P$?ZhYnP&^j2T#6W$7GN9i%}#*<{B9Jhar9!3C1Lm1;X$4VmP zU6*s;YtC2sEk3Y8`1Y*rthn%~I(?Y`C0{Pp~={^LLU z>;Lk9{`$ZC-=F;Bzij^M`rh~ZcHQo)zdO}%y$`M{YSy}N$LM||iH$0#XSFu2el-QC z|IB<~Bb#KGjO=dz&f}!<{crS0$tiU>n#bvpvuDpGe3Mw=rMqj^G^f7Zmh27Em|2?C z-fNbV#fsU1C>DHkN9@z-}YgQTO=wbxSdWGLu=y7 z_P+ZDqB&rZc!GEO)1l~I5YWAj)KP^aN+d4x0&N|4Mp5ahE^0`+MDDBEyI9z$XQ8@ye7tNi? zoj$Do%ZzaO9=uT7tH|1J%ay6>#!u@h62<5i-a1n1=zpz0146a7*OCQ6iOJXK&9 zw^b{EBk$ih_Te(~B21p+kM8cdJAdHTWck!ZRm(5#mVp7P+qsKJ8SIcw@NLMEjWTyI zTz4iav!@#f>#P`Td%2rtE*{uCn$N*w+i)ItwTuYZ+EX*znm2M7bH-9Qcl4;DO;+GB zqbA7M8be0iTQYu*9kjMnk=%D@pyApedS{#?{X7ZD<@UmaSrCiQa~vFgGQoYzA*jb2 z`RR8S|Lhl6{^F+>zFfg>wV&EC3Z#vkAS-yUo(`(wYSczWK4q}pMniG46h<=79;@Yn zhVTjbQT$h#KUToz9arAOp<bL(+ z#p^FtZ{YK+^H=#b|1a)&_l+Z)!T5M42>;3LHR``K9QFUq2lEGS4ng%pQa5@~j2AhW zvjFuS4$tw`pE_fDN=?-2jF(o(z9sEk8+AR*!> zh_!dkv@iuS1#D}rNbahML16xL{_wu^j#6qYtjnCShWxQZ#gn}6E|NbB4Y4xd90>Z( z9y+T2JNw*{XrCy)$eEBdE_n%*snLLdv`MQAw2avIHV!{#=S&^D7AtC9mvum(Ng^GQ z0sLQ(rp=C9CJ-CJi$(xe(p|-%V<>@U8x_-_WXwSpRS@iO6=cSnDx?zqR&OMI!@ZRP zrU8(1J+u2gW^;sa`NEe|H(W-B44cpwo3YcGJyxU)AKThf50VO#|2Ek%e0#F>LT+}) z3Qo?eUAZp_mtV~bfc8gCPDkeSqgNS6e0v7|=))tAXF5NB^cVm6KeqnfO*hoK!Q9xK z4wkv0N)}Ice&^=OpMKw&e(+xZ^}qW1$v^qU?Z5if^?&$_TYvl0l|TEATMP*BUVpJI z02~Qs0>FRCG8dPotsp=T8j69#Zg9OWq)SbX1!7-LBAY%u2lP}(7uyCJY!etq3wy$s zp84e$-}?8zzV$!-c<7f;Mt=EZ;m^OE{iEl--+g%a-sq7Bbmg<l=$m%Lg^2j-BOPkedvY6JZ%_7-Q1Gc0UTCzB2wzZ|FB@vA3a>N4ve*2-o{8!| z#)2|ynqV)ZV@&NV_4KsCK5RV16eSJ}-hzywLuxW-@07`UZ?Q!{`dkCNF?ZrZ*2Gy; zCrr;4m1`NoBwEq7;S#z<+640>UZp8Ovmpp6rHizg7g<(XZ&^x5ksuW;$DKnZ+lJgq z8F908#;0QYm_0%R#)UX4taXHW4=M$j$2PB zkIIX$(v|775j*pz&#&(&tGm*1@WEK^^>ByYb8F(v<3~K7Pk;XO)JG4FzCRBHpbw(L z=GAlf(I|7ysQ=T4EyQgHSh#HH%}ALn(W0~Mg`cMk@3WqkM9*Y(%MeZ!oTLb5!ZNOS z_>>C2wLcS!QoW^g*fvDbRNEWhCQZXCz%>jFkDLS@n85lE=!mB0lz6 zQ;~pKI&=QS!)x<@{F5tx{qwP3etzSalM%q>6o3V({}pq`58Q67UObjP z92B6yfBFiNMoQK+WeR+JvvR}Vt9tV#RX#Kmd9onq<*ADSKPwTBh zYpnf)&(1;NWE9_gsf3@1i){U7rx?7#+P=srj+F!3lS=*jsI5Lc|n4ldtP^1Wd z84AWMIt`oRciO}HSh?2U0(LlEY-mZ+GNFT-or!tZb*2LOt=A#9AbpJuJ4%KORQ!eu zq8?q=b~0y9n=M)F-MqGhy*M*;QtZ=hIC1#5Ud9dQt=Gjd+hExwvmG>t5g*a2B1GEtY#nIsLJ%|PIflo#o zzy09sr*|(re=z;ueXsUTyXOy*#h2SYTBMeePBh$Z>iFu$*iWAH|M33B&*t~v?mPM6 z^x4l=PCZ-h|M3^+zPthw2}+Dm$nJtyyNX}zEODZRtgIsv3SMl_*)`kwVwc@$8Yp1R zV9x9PDV_j+=6fw=dE=*xmpeE1Gz2=qsgDNm>Qv8 zQ)S_(;emVK{L3Fd|2KatJzNS5R*%|f#pwwcTUM8?A@kH$sr)^$prk5dN&`QsebThH zyViK}T2KBrycE5*IhCnX$KWupbZsW8RZ#)aKo$KG0FXgnxXr@{TG-u}pf{LO;~bYk z(^bNABjH~Zj&Pha86u%9%6x~}LfddDebsd+fIC{UcC=*3rZ*1obd?`%Itckm!jm5? z=A_;=81;}D;O7_RA0eX}>o55iP2X@-i~Kmip@yh}t5XNE1~#oI=(p>lE;jx&oxn5nxlP%wAau@cO&o@{g@^nM%9 zg83r}>fkGnT_WcqDEe$&6ST7GyKnp%w82 zf|MJnc3Znboo&H~3ZfFq0fY(U4%O#fJ^Joo{<}l+LyIHqK!_5dYe%*KN*`=eG6#y& z$1!BJZHUWI{}c45NR}L{2PN_OJo4f7Gaujci%`X)SmSk=Ao%R*h4$STuf5)?s@n_O zrxebdRf%?j3l4*0R9LAa(5U&goh#Qv|2*c1Tq3Ej?LD19|G97mdgo zn#74n-lE_Y9|Im8LLoWyR?oFm&G!3=C_t=}@R%=;2~PpQRUNCBZ;D z?4Uaf$^Xp@k>TD>%#ssVS3ZbX5RA3g#b>uJeEQ(xr*}>~MqwH|cyH?9{c#mFV}PM? z+0MRvM1AEwd$P`{v2(Dx{(f7-gMJKBTk^1^TW<9+R*q~Xvf@(z_u?obpG5ti*psOL z2M`q;0lSt?AG_DKmk|&}Gw)f&zdsxf$+};wd^3c=RqwvU{Gsk$6i~&V`H!!5!S9^d z8OvX4O`dN(mC4<^%4aTL{OG#=9}Bc-;)MM#sE5?ow$~|1ehA0F1*H*#?T4Aq)CGG1 zU9p#ubQj=BF-O@AHz8s&>c1cABuehD zXMLGAxIa7|LD`qXfQyNly9}|%WP!b=^S4k4T|hJCQ5x=z`vnWgUN~T39LpA)<@D&R zLM9yX@$r>`xy1HXP;(LZ-IZv?gFmSS1?1WYKyMIcjB-#ZA2T2WrcnH^F40%a9Af2) zKjR-73cLIfFj1?O!2qrQ~$$+6F;YwUr>Ys_=n~f6#dBl8!WLjY6JHNSpY9&W)aoo1+vH~1iR=ql@f zw`Due2ROO$4c{AK8{_LYqJXw^q%U(KZ8%h9Q(MK>E-rlKUS|zIE=Q-^}CB!SE2#$cJa2W+|nGHxUZf$zz_%3e!+hAT{-R<*LOG%>ZFAY$fd2%Ms7GGtOwwD_lMmhr0{s&`cKDnmVH&=R|+$jsE zF0AQe5SNiYRbDoK$zBzi_VB|AS{BDZ?%JHoEV~(&e z!yKutzcbYO^*4Fx142n=*0hQ`-Ra;q3!7v$`G6^$A3mj~5`fI6UL%9JLp2j&^*DKg zl~Cr~z8#ah%#vk`Cky9~Cr#DMM_xCaEin@ZiHeYs(XkJ%o_KhNH8c;O+<}Umh!@Y# z9z1yL&h+8iQ`{Ri^=57wNHqfZMVzPBl&}Ta?o3Bn`Zs;{wCR%%kKCEw*;((UFyL6% zIt#Y-W)l2b4r(fPbXDh!p4heA$>vlvK*P<^`Wv16qP@1qKU_Q-f78z#Ne(r64mo^e z3iJg8P11!sdg9}ug4unZi3DUa0do){&}zY7g?*d_{&Q6Tg`(h42s?wAfzaNbD*6;5 zP%=gl^^tiPfhyD>AdgnDbjBwNU}axiJ9pWdpknGAYl3%LcD!+Zo5r$WY9DG%^~xnA zSeJSZ`LR1@6NeNOYMMm-U)P+%^}2fQa)h*Y6=aO;qvm5Zfb-*Lt*#{CKmI;-c#rW= z5%zDj@%n!yTB8NiK-SW(gryG-Gjx{)4M`L?p58(TWH^O(A=^jiPb{W;bQf?C^4Z3~ zr0$HJLVG?PlR3pjgQj~AB09GR8m>?TM5a8pzqc%w)PQ{qA62RF7cU-j#<^{g=-f(( z8Bpk;^z;-Nkr>T67u0`q%{x6seZT*NR5@rlxF79B4h0=-;o=b{Fj+j#@?Eqx)ZJ2{D2b!8F7;`em7$-31N;XQG{j=Vl?RhtHVaz4y)# zL69XrIT(Eb?GY68#1^ObMlWXn^T|*Y*}$ zdFaorlLEY)du*UUbVyEC` zz2)faNYNW-j_$YBHQBw`xWiM0`2?H}>hF>PjsIUnu^YL}qhx3mF+Gj#QvW#>aPr~2 zQFQe}>9q@4^9Q$%7i^n|EJz=Q9n*!juF#mA*>Jh3yES$3vro@|@@d_*X`v4Qmh73s zmCHRoMUL{#ec72qM}tOokRv`EdA4pe*4*Tf2z3YZpCzT$1I=KH418tJtDoO+bg!Lm?Tc<1E8>`fF6ngLkKo-d|EHHuUXG8nZ9+R$_@DA*YfylYux%t@UwPvu4lb&R>w>VykO3 zNE?o1E+Q<9Ss{{M6Z@<~_osCGXFj@l`OAmR-+XlX>5ZfJ7fwI9I{5pa&;9X_Mt}01 zz8`$i^Zie)v1*n&0=eocO&u)b_6%U;HpVFwtb`uVBLe+Zw}A6+DWKuE7s#BbCslwi zQ3N{|pnOgW{l7lh2DbI{iSti;OQ!a7nTYyNP|#O!^m+G-yWR@VPi}AJ@4QmK{&&mX z;rt*4-rxLA)muB7@|ms#`A6U*TZ8U~-BVFe5?do2@kgLZtBfQnf zLmo+{HqrXO^4}k;uL5O1p$Z{!-T$@ z774Kjq;EB#EsRATrYLwn3_=t0h&V8@DN+9;jK-nxoBH2Tgx2V!c%>uv)xv>j`Ty4*pzmPJ0&=G?M z>BVGmpoDIlD%lYk;`>u)kL503EWh8CvvS5p+o5cOU`GiUObDO~^>6O|3^Iz*qi8b~ z%NLQ&RMa=RtV>cYa|zk7QhlhL9WI{-{QzF#+OBky1+uXloL8hJ%Wp_NZ7C5k(_4Vn zQnGZKp$$4cp#f2CoJ!Mm0F7;vm4>6O6D0-Lj~A?*LmtjwIi0ycK31aK5s^75Hcu2J z&sFjC*f^Yvm)me}vh~}a9eI4S_Qr^4t>UG#wiQML*pXtptv?%;2uYHkv%bYxw3=c7 z+@SQ|E*-Kx{I3WtH@2m#^QnD>*+bQ(3o5%bsl=M)b!o?&9wnLg}rxHj=aBwK&ydN`8A5he;+>@4Ups3 zk$ema1F8Ls&mJY?x}h>s6!V>!6*ZRL79gKDaiZm0x7)t;;QX^I`g~8ABgC-}76yL& z%$9BX7vJyv?uQ-Uf1gK0+0~ZZ$+PS-jy;{8`qk$bo~@`t=>vQ0c{$0j2_@p-SB$Ty zu-jq->pX3h--Y?9Ud7iDp#!_ofoQ>;4y%d){eRE5=UbkSSI!^F8m_{E(El4ra%LO; zPUUMa0DLOfyj->Rw<_L>`d_wI{f`Lvnl&Od)qgT8^&j^pvw#1Qd*hAIuJ60i4f)sn zvwcYKsj@W#>jn5pX401K;+8QAD8cDNPJ^xi;bRG5I zg-eq&a-?+m1o()2fG&*1tAb1+tDa~SRb9uiKEaJ3Zor3Mdt==2MzE3BnHvvv&JM5D zpeTdD7M9B$oZqbMi-5-P5P-i!$JyjZLxiH{_l2^+AA)^EIFQJK!D9hvYyL6Gb=^V5 zr$HvwPh5VA7V#V1x$pFrpZ|L4(Leiz`F-b9eV89khJHUTbn)JRpfMP29~5>i3h-I_ z6@26Mt|S&TRt6T4W*oG+W8s8PIEuSPuwETF zZ{lz$U{h4y=ndzb!K%3Rda(4vYiQx`e;1+s<&Fp}Ll#}rUd6=)%O%{Ntvfq2k)xP4 ztGY)&n1Ni`7h{>eC>l5*EV_wZ?{!tf;+zx$w!HqU5DUVww+-+9hKRA@ z!f43=HLWECai$Dir4#e*)?%d7mpZqJm?0(RV1RmI(+BHt;;?{I|08;)J-Gdh-x)h| zZ^Kbfoh4A(vr{bK*e;8Po#Q1A(`^&w>i>@EJ=@3kCruyEy?UwP(ZsPY7fNq6uF}9f zH>kMR7Qv}#;b_&BMiw!JW0y;2n$Z`X_%F6)NZ^w2LYk+kgFA7E@?k(vRd{Ux*Y*(K z6$wDeoj3)zv>h;;g#4NA435-aCKfP^3$C|U-M*~od2UJ^-PZQWU0cR!#EQsu%kG>n zzu8)Jmzexk*N%63)3IwZ z$B$vY5&xzOhnj9=RY3~jmf;y|gYO6v;DwlEF@eT|N6kdSwp7`dg0y*}!n~F?Q@wq% zc-?UEhM`@jo{d>VZXD0wFq*r4B%dUWIkR9~4ECb&L-bSO+B$c>;oijA=l9Nk{{E$J zK0W>H1Aal4Wl5u9@0>YVhwyLM-1q+CzT4wv3+-|TAXGR}M4b^CGn(rF!lyMCaC=T3 zlEoRiHYXHkwkXJ>b^bH<8l!s)XHV4KY%N}HLh|%JI!8Qs#uU4`nv6-j^ai8E!3QJW z2zIGr+@S%gk08$2vd1COFK!f4%^HSxz3?FEIt%Dr_>ObeVZ|vK+qdDF_#XnL1tMW!qocdt# z+{agHR$BOTX7&W^W9Lg(nADL+c?9{<|HlZ>CfTq8;O~Ga9NJ$tdc1P-WLbhKR4{x* zAO0H`P~l&TXHojg=1&XuA_s#7QLdFQoYB&o1xlvL7A%s2Wtz)nsJo8EXkK5PokGd* zSqfrZy_1NQtIpqsH(HVQ+|t=&98-;oKr`(<6$WPs;J?|SaOMcWADkXXXYk)DL9#CI zviUuhs$J2eZf-40=u&gMhVmL{`l5vP;J4?$b}1Q$5VO?7lJMK{$*O}CVJ;C1>*4~L z=|a>u2!tzU{7riyA7;(JgCJD8?T~z)oH;r`J1i;yO`~eB{s;b(sQ-=te*gr%-J>Or zgcoQ7q$NZLrj@Qj59_Chde@LU7YbG`ef7WnlW+gKe{uG+n>F|Q906_w4~US%B?jQ^ zP+J`w-f6VUpgYS`TlC?-b$K(sx}yzYhMZx`SpC+a2Fo((t`*lKN-2+L`@;E>mBxal z(*UU00(a%$c5;L>1z4AKfA99muWn|}ok*c)oZO8Tf*ps&*ZKPozHuq{tzJo6IXI$g zd#eV1`3X4yMBVn*6XQQX6#RPk_Q9V$eWRuD?cRLLYy0JJ7U~Fv9imIP;xKLNO!pEM z&L45bY}M~aXRhzBX!*hYfV1eT`f4%u1q5ttEfYjyx?wwnt~ckPsL}6|AK5N9l16y58=~fskj;9uz~6JS_P5fTFZ>x@z-yF#`mgM$NWPdnaB0 z%7y9&J-goT-}7+#@W=D@k4LiRPg{}1US0rMe>TSeZ=V~V+NgZKt!$}9vu#c9kWGZ( zWQDag^Qe}99G&SX0r-bNInHK58}7)=9XlzF6xGx7L@4!W^bRcaS&C&29*3V)-Dt)Y z+}ul)QLt$^UsZ>1ZyPDxHdYGuskzl#b)yshPe{eIEsD}~G2znI@oK-01-djzg41{U zQXqROt$wm__Ka$yI<4(Z;zC@1ZLo0Wlu$)x3$=GzC54IKwK6aWAiVkLI>iv!_z1n# zn`*>+vnR`hWw^^;K6B>F2XYvXKe;K1n28?;gJkesI}n5EN@ecwp|hWSeEh>}Hc%Wj z-B~+^4e`q=l@{o(~dZe`|uby0<$Py*T_l-H*i!mkvIjuDjI^ z1~(|tLs^n;?y0~RvUJ{ecd%-y6;6^q)j*oPez=C2Gxf2m$Se_%V#AA8VH=x4ht(CJ zZtmRSthqyYrw)RQ;iLNY{JF!-j@;V$Ge=4$^o@dV4gi{bDiFzXCy(>2u!zCTlpO8F ze{ZOW3DWi{)_+->2eOk#ggVt{Ox9=4F#jpbnSn>uaiX)s&7RVtBXh%;7q^-;+j z-w&=A1d}sW$H9-Rz^{`(Cv-1zSBqxOcF+h{WONrK<4%4D+9|x8Xn50e`Rj z%{3>I|7-n^d0JdI1wZXSC$YiXz^+Bik zKN+1hEa12((-9XAM!;FYo?iUmzD4CIl5M-g7cQJHgpQ=&Z}wj`EOD=(lp3m`CP`2ki?0d#~pk9zKVf_iE% zkT`=(1c_y6zV=lPqn$5k#aXZll52)nHwCN50it-{PaaSG>U(WpeSGno4;Oy@gX7;E z1=lkX^0bvZ{gP+p=W=*kb!_JL&vQ5m?B%qV{j!6&otX|eQZgXGxi2S+7P#+LTF0Be zD2D7c09lSOu)jz44K8iEP2$fn~kL_=bee# z<8L%2QVCj8;Xf|>T&E!n&F6==JTsmMT_uz`;kOCIyv^*{b; zEVl$~L+v+yR6I`>sh#D!milY2wI{3+ns?pks9Nd98q%)#AQ^UW46uCpMLVIW^SIkN zQs3%KUelXwvg6>9Jbc0d1jaXm^IEZXM8m_Kh^+15gD0M^9D97DYQ7(nUvAg&5AL6O ze64n|J^JLx*K^Yy7l2D2O=6rqcRB&HWFP<#5sNeP931723=0Be$h@f|%AJ~Qr<^~3 zA#3)O@ExLfpF@fUA~l95EI88V4jq1flnNL$r&m-MwZ~d?NJyBbP8`jiJL>qb;3o6Y zt4Hx1sW$s7#ndqe?@q*8unX%f$GvavaAX4#lLjky-MobVym7oV6w|{MdVuu;ExfIN_rJSq3=*aGBD3YvB2HOKm{@{VPqoX3msO z9?3%i8r!2pGf8ldWRC`8r*@{jX6Y>JHUI_3jD(8eWa-q|SP(2+ESoq9N>cnYyMktx z(cKV|7UsIle+CM<2-2kRArXR>(Thi#WINAK(h*-aeY|@1Qt9+5{3z3_gzM~?JyHCJ zFq!LgL77tr$?<@D>VE>0!F9~gF#Bq_Gq`OX$Tf_U05B%94)%Mo>?RI%+xkq}?u9Y$ zV3vd-Mwkk~2#_#oSJncE2Hmi}Oe95WjGYK5;*J1-QgA*6H3EeaJQ+uT{(rUp zbB)jmYv9)n1eAe+4|Q1`6PQ%IF__J&g{Rr$fA;go|Kv~3JiA$ccf9uQ04wHqS_?9! z_8Lz@GEBl|KWIkZ!b($SG%i?PH_Z;465j@?$X@l)8G0xf4%F`Z1GA<;gyrDV06Ofh2ft)*ZF^g zYh2hkci@}PobOrGJ`0E4Q(HFo=Nf3p0SKP|b@ zNFc03i=jj0u1LyemJS)=V#Fx5J*ph&nIf)j^PrYZH1kIv;97T4Vx)4u1$kEN~pHq2Lsa*>Y{eZeAiU0 z8_K~BVqRy!@rfcs;Q6TsE?H>8oUDy3;Le(BeS`ptPuQ0Yi8_5K6X7{o^K`5o1N*gXwtT-RW_I!G8(&T9xdr4` zuaGC*vxU>APkgwHu3UYkhnJ?Nf_9OYfUBoCVOt5 zr_D%YQ$kL-4MAv7=2}@ezYUb4+%#Mrk~1Q5oilLIr-#e8$a5K}@|tMHS+-gMIAkGL zXv_>TwvI7V-K8xLD$ZDg{VbuGk{;KDgJ4&#Uu|Tc9+hjctcTq<`fIOrCyuj|g_FBE zcA{}ACb9Dxt|(kOdH$OVr=HCo{cyPMPP6Dq^Mdp-VFVs3Z6tyKa)#@aIQ8Ibx)Wfd5H!k4DsQ5D53*E<;guVOoyz2)mJrjmE!ti=D0IQUCzs zQV!Kgpgn|*-$J-IES!T=p%Wv*xtoBQaQO88`m(8`4hYN~us_#p>s<>MlNyz@MXg|$ znx%wC+~Oq*WmT~uez|-ZHO4-sNMnQSl1E<1(1Rf$|Q}qKxDE<0we$S zAdBXy%;79SH#(S33cA5`uNDm!kkYtTQGHxTx1s+_R!sC%b*JfrfA#Yp{D*%z_S5g| zy4U+^XZpI%8nW^2GUXGv7T%y6HfV=kS?haub^gJf*Dfc&+_?oe(q2HT5V2f|Tu5{# z2Rf16Rw15E`Q!}VTpVWZAK{hJjf{lLu|IR>Kf;m9 zfbs3NQlPpeEdOeUon>Hqb=Flj(z>&d4}O89$mbc>u}KVnUm}WwLT3K!!!YFd}X)F_Aj&On;*r z;aP-}LEvkk0NqLrPqUNXl!Sa-(#)*2-~g4NA5OIThLx3}i=p z$yPxy)MqqkUAYhy+R4g=M*QB=r6#m1a81ohKSxdSy@I)88g(*cj3zCOO*-RQCxycJ zPG1@U1!|BPXYHV2gjjoj(PT^YLK|ye0{^1PGr0mj<}U2=m{&Ty8o=$CHHM4WczR-( zX76;Tia*9#B9U-y9xvTETFfLN_U2;+V(1h8&w229w+2-*)-gSlb?5%OOBX+STD#H* zj>s6y%WN;pXfMg=FG5*A_3=&Sbwx{Uv?rjm)X`&W`^3TTt-Ub?+VYsN{pfy28|a~& zmF07-yRVP#yFGK_gWH#$KRf;D!(&e#Tzvklfh)x04@SJOAmOhMT=kMnrV$NMf!KuYGi@ z;noO{4O^gS?j(fAuHU3)Bm^zy&z(H{Waz@z3$5S3(e!&)4u3deE^zJuE}Sw>fj9_8 z>k`X_2DJ{9aI!e-NSTR{dd(e%N;qq%K6v)Q+qLg)9|lr+{v85xe(=o zdZMQyaaHpFH*n>S?x%G^(X_?WW(UonzgBc(B)_2LC-NUxogComAo}n$?yf;$Mb~jI z@R6et3&4Nwv?~$6Sjj-iXCO2keI?Xzk_ZS-i0>e)#xx9n%__CKoFFfV?ud;8lCT?% zL$9&RTknL;o84yybc4GzMIn!EFAj%ij`6ORRDchXKRTaZ(}o)LNPL5$YG1I5(rai} zAs~k}ut;Px(9efW#deP*L^_240WFhe-VqQzd{-o=+cj%t=?n0jNE=)73 z(r%eMHpM$8YLM_@L_226G=b8iQl}d58)M6f9mKh4pcH`?$90_&Is~o{uv+;|905g) z967RL<0}FjjG;HWclHZDs18;PN#_Mgg(ZSH0w<7!XKR~4v{DPf^nrbaQ|GFeI>ef2 zAQ_xiNu*k6#NLOdk^&(b8AxAm6NnkP(moF?>8P%---%3V4IENFSB1-GIZhNWo`P4P zH&7-9)khX~Z~69~S{up2xs#ShK6M}t&@tLP1ApC=5g?qghYKx0t(Y;;{F&2{KiEMh zx|clj1uuOCEx0{X$ISwcfW|K$vAa+0-3v*EHs|)U8YoWh*}wnhT+8R5p8W8NpUCJe zd*RUf!K}5zDJ8d0=M#!Dw7J<0@VCE{QgrD4^xj*8{5)%~_wTzqf9TBT-+deDdySqv| zr!&II2O{mc+nYOoh;Dkv7|mTqw4kc)6lb}X@~dq{3n%H0sRBXEvXD6$))19*$Im?W;73_f zTVJ98c|lV3;T^?%-d?R;r~iMY<~>^g8-Z63Y?RoZ+=bH{{lEIZ`&Rd{CzDpvyOx`I zKIFlFNYzBO%GHhVCZU9BVe&Ju8yD0+wEra;#s@AOKOmuAEE;1p^3c)<8}0Uj-=`~7=EvjhL^$&0Xq znMMaqi19lM342!qaiod}lLDx|+n$1do;DRLdr*J8-Q8ueJD>v<-O`onbWj;KibovY zW9j2B6@RN z;6{iV?i2tl5NBBwCUyj2)WDzF5n$rDoEc##e1V7^mM>2J`R5Q+o(W-S)*T+6F4e4;QB^WOpu_|Nn;LSn!-+`mNRqN_o$idZk!iE%e;F5F;|e=X3B0ikRn6d9jyCBq4!d>zrAHo(&;IeZ&wqAP z|17W%!hoWmGJAN(+{x`Tr*}-B%UEbGywYY%ZsM~=HK!zuI=8CluQz3I1hVT%gaw3w zk7Ld_W<~BTHhp{PJTYZ64pZX3wsh38H*C)niH+gaGgOKlnmniUmFoXf7HSI?_i+`| znCUmf!Jz1D9%FG+L+E55EreYrrXhvpPNdcjCo+1BLajWsFDG}?~EGWZOKNC z^{e?!O{wg!5lWptOm7@jgl5^Z$BAuC({|AO3?Zvz`s(1F*W(^DBx_J2h)TK{v6)hc%UOo7S<>a3nFENDo-y6C3 z`PKT{9p<%NE8YA;*^}CI0I1RGB6oQCSnZuldmjwQs=n~mV$1igpL#x}!DD0^)^MW@ z@tDK4s=XrsX6F_8S_6bO#cP+iT^X)ECUw=OX?T3yG8zYGtP`G(gT*1g`a4iQxI z&jtFos^5I~3{)pC%6Q;EHCpR~4~9;EJa_ovSlv~}7Pp_^_M{0kY|YrvXnYRmVVJ+b z7pDM5C6$)G zPi<xWSV(%>TJ(N>?n_DvZZ%Ddyd>~<>{aYx|c7c!F8kkfTJzzSO zP{WTjyQ8;`01Yn)G)FeRy?0lHs&r&938yun-eMWIy}wk45BX95<8&bP5)I!*<0FAL zc$Au%cx(I|FgZRyF8e8kXRS$1CocwM1M(F+Z++$n$v#rQ1019l{z-2)2e zO*qC-3fm5-u~}2+OBOmaN6wsoe$7$?Lo)0mFrO3TpH<*UM@^#|n`O1SGtZ#_%EoxK zoaHhB0qFhFgLN&%Dmlc%H?Iv-qeA^BDh_8(oagd|?&A5r{F$aLZ4JtT0mP#rg<5?0 zwg6$;3ZSx&{>3lH{`lL6K3LxOa2~Qc^7GFdzh255Ka)IsNX>!0u(|NeBfUM$l!~O% z81Z22_Ja|#D|N9MzFnO+ciFNPc!G2ki6>3l5qoS0Hg;AbCaLzGq|X1R>1i|5~vP*imy@I_PMMpO zT*riyI%LAF7;d2l@t-Cg*d3}5Fl5Jg6;%-$qUC*gi@PoOWJDSYwj%Y- z?z5UKymFp9CH-3L3P(g@X$-Pe4+$~=YIL35_lNdA7~l6`Y7Za0TSMU;1ZfGgqjD#m zud$fuFX13cUX8{Bgx4FxA|x>Kz(fU!a53FTSB?O| z7KBf6MN^Qmc{LlGd#a2-ueT&SEQn$_7;Ns`iS0lIhRCFf>Xyr|Ufj?j;H+@#M6~o) z+g8j-`^j?-xH1Ib9n%f?sM;R*4@`{V=Z-PPN4XXvWjBL??|;QseWbwLifooMb6PRi zFjrr@eE89w)1N#(_x#DZ=Z{Z+`u?d;9vpnUvird}Lr$5PrT}e^=jq%bY7h_!v4Px% z)OX^rRr20job&IU{rLUkpIoiEGiY(Z6&xmShVslo%66vVcOf7^@gJ(y`JH`z;!YnXLmFK!?(Um9(xuo9Q$>5Em5LPorp64TQ(`fk&PD_{sS% z9-sg0qkVUlI8h+jqz)JI+lLxKGgt>R_dEP}r2VT83YQLTAI-B>l#IhWPPuj*SVkih z@woOW2oGy$-x((Sy}7GMBXctYls72xYSgh?q}w$zqzthAcLG*h zKzmsbsE{b!GDt+BZR{=tj>YPvyG*|q60pup4$@8sCyPHs{YeOsV2P{sKc)bF(a?T~ zaY7zwITZ{*tPC|j=*NMSCQ#fW2x@>uJzA0M-(0fk6LB-@rvj*FE?Vr)9BIrPJ()js zMuF8H1BHM^t5IUAz547pa46`#0WAJWaO^t^F(=>ZEZ#KKu=JPT6B6`J6O)QeeYhg2 z#%grQXtsRHk7yeWd23$f{pQd9*IyraG-;)qzH~T! z@kssSzSG~FvfX}*E*pf^9o9occ6hKzt?Qff2pmjgJSzgoYE3l%F&$)=FP}T}{0f|h zOT%j&+Yr2=%`Y`?ed$uFcFwtG)%%U69E2hPVSaS5Oqts|K3400M4ZQEgAhkRdxV(q zG>afz^{SbFa(D!pYxJLC{4Tb2Vo%D{K2gYoT7}nI@~$;yuUyPrK9jz5GG+c~?!vjI zuOIaM{`&(zeo}L*-TDBu9uBL0xz2IBRPHE9H6}Q$d*|#+?OOz_dnJteNB}q6nH7 z>@rrgaX3e?pgvYV$r>7IbN9WGy=?98P1oG$Li^P2DnvZzw+z!Csjii1?ZwwGST`%A zxLc&G@_7Zm1X#rFgukn9gc89=x+hQY8N|%M;v;0A<=rtLi0G_%rbF(XRPVThEA68?6F<92R4o8IxIF%h#SascX$PorX3t^kRmZORw|iu2MCk# z?)XlVo*lY3bLR1_;}36^E;i$7Kx0a-oB{!DA1`AMYwqw&$og;{w+|QC$%3S~rEMG9 zLqzP*boY7n9G9T}!g;662}X8EIEue1K=*FL&IN8=e`@TSp$fp;kwd!2l<8XPLS!B& zs{`V_{tOaz&wTwr&W@1~Q!`Dao2a=u=(c5cS9SFw3e&}}9$)g=!8ln(*s8(LRxchEf#kDiJGY8@SCK`vDwKbNDBd=h5ub-}(fya;D z@3{8oA5Z`6Zso#J{2%q7_mTd;{s+CU)~*Dik2ks20)j9ov|73EEZ%)zwC$*P4GU)rP0FpXvev8clzJUvby1m-KTk-;P z*zYLs%s&kg^3hg{urQaZ`AaCEu5f8sxLCb#W(PC9u5$j>&VnfZ37?;^37tO2wG2lh z;@#U*{R$S`3_=lyXhWn(cn!S>sKpw7?|aCCNO3tbB>*3OJM6D@aqJoh7#UV5CKwdP z1hXwSNPA&T0#waf!NjMT2Mw)W>bC0bF3|i32`6zm1>!95ojS(8T%RZda)7$Q9w~|j zqaRm4FTka4n}T2ssr)kdT>te5Fr0!JZRqf7w)LUhcOtMEy4|hew9_W`F|HuGbkTwp zVQ!GzlF*_9VdKB9vG2&`dt;HBGQsU|8UZ7W<`PsHW#4FEE>PHC>&khdF$@0_t3>hN zibmB{x~i566QQ>JDC}JY)$cbQeAb`2a3pE^;P$Bl+vg5!oj#DcavIw2C$a#dIDVmp zm^U`C(&~c{j>2>)^4t|kL8wWCN7lBLL!8zQ7GD1H#`RzS?Bo|qIg4lA>3jwN2ne6( zG|k_+PrtyllLR1!4p3E3DF#l|e`|t{G-cluuv-6rw=-EB7!*jO?tQoYT)hBLCJXqI z?}t;l>p>;DM5d$pOBeP&89(&NV(t4=h1a^$7B1KYRNd_RXSum zM*DOkyUl}n7NeNkE?#OHd$_#@+XBME;)SN2E&^VBQ2*W4>XBqhXWD#4yhQP} z54A|OuVJkz;#L&0HaK(UWC1-3jpx!iR9NNO2mt?~;q_B6h17qJ#M)`+5$hgD!0x-_ zQ2GRTf_+qtQ^eLFfTNMh^u-1WH391zCvw*gJ51AaRt^Kz?OS6W87cS%drtJcDU2Ni zq$OkcpjCyvm<=^`Gj)LBD`l`q1_2(mHRY~b7aBi*fB47W8vW_lBR}Kw@Jv=tQ1?e` zY?dt|(LtpKD?#PUmly#>@n3GKSZQQ%WEi1DQ1E5GJH=$#tN&&h_y(#xQVp?TtQ`?r z#vLL^m1gi#M?mgK@InzvVI9Zc?^^kj4{!bDGb~W@G(;Cx2`XXvCzpP!HvB(dtXQZ1 zQvv^W-8%xjwzd=`!2hWK^~;?np3Js5Z>ku?lS_Ub(X9D(xwQ+A|1ZF zT=5ULw*>h=$Vk)2f%(uL@Xl)dicVg&&l=cIBhSM>JWB`cCN7!_3<3=QeZN0fFQ4@d zYBi|emRtmw2O$Iqx96ENPC#H6sTY*eRPOb!TsehJq?|I?jH*sZJokbIXD!Isc1;|dc1R$3yk`-;F*npKbyrH?2sYh{py^*6qs30-66c^W7Z zS1#DW&Qa}sqm_z$A5y4q-qfzUUbTQLMrV@tyDBSItiUz430OT;!&)yE({Gz(2MWgi z=#$p(J$MrbQY@@RcEVHIDpr-#S2IR4DPS3G$FQAlDPJ6@S?=ZZh&Mt9#4IRd{$QlC zP6ST7ZL)61O#NmV7E|?UOZ(T47V~wFRIdTb-$E=MUpMvDc{0>hLQGUeUApe1dcMj~uIZvHFeDt%akzYKs>3*v}mynIR z0qqC=Z`tayrCmJ&{_EFQdcv{65kL{fB*AnB3xdg8jDnI3O2OxEOInTe;@JOM*XEa7 z!})Ek>2KquEH?Jj)%YrQNM)*aDo2+hkXv1bt z=FVTroIk!}e7D9j0?QyXej*n;?r=k87JS9aXDY8>-gUFB?oQ{P`~AD`^&yjR#`84L z*WpFsJ~vXO>t^rZFKJFy(RT(?OdJK*4}>Yfco|G7`d*TONEIy9d-xhphE9;UtV;v$ zgI$eAo;q?6R;&`HO&(+TQ?htw+hCqS0EVM_8&|8Z_r5n6Rvx0k(q=GiPKa`V#`|FS z)zF-rK^gP)+b4?{>Cl(0AIWXt zUWYXUDI1(1BY7J~vXWX&5oQpZ?G{z3wdP^MvNQss#UI&C6?A-0`6+*7p zUf!{`DQR7EDmysAf3O0^BfgqY5SDgyWrtx!LXD2-j^6p+Ka+9q@cMPGRdX_C6#S@inlbXfG3)~XO*Df?}ucG>^`6^@`T zyInEvw8qW?$nZNh(yL8CSE8#^@5lxvE*RQjoGvT+> zoJZWsn-`H4P>)UeLTmc(v?Oz_DO))^_p5LH>Hqt`&;IeVb6-x>Kk6^K(UCfLI%Sr& z@j&>!EF5gOKXClRNmAl>2TU}%bO8}G)@R=xd>h=+)hi@m&Vo*ze=29uZ*-@<)RhvJ zKJBSMdq%A6^&GF{s1_MP>F<~VU&|| z#8A3J1soXLVX%g~H=9$WB>SZTv>6T_?`z#D-1|LYZvmm1!;9zSTB9NxxBk2^AD-F^ zMbY`=&7ugFUu{$(P;t~E^&cHk6dJyen(tJyP@wSLFq*9_uNlbLG+tPE?X*v?nhNqFpls*f8FoZU8&mP&?Nw8O!HdLgzACwtleMS+jMj zpy0~IcZSo}4AbJJtA1fgH+=+HALvRL>2?m))ov7Ds2qK)I(>qau5I*tG@qbiCQ z1pIk(AUS8I(K@^S_NYZLWdR2UT+??)G7T^25QJ$PMpXWE2id#BIa?<(JOSs|dqX+C zfuxQnKQqgRd-Sn>K?wykgIZh$#n!uf?{}Q~WcamP}FJ zRg^S{%UzJSy!W@u*SuI9{Xg61R}OB{{ImVE{FS{TcnjzA6c?uF_fJ1v4(ER~`@wyT zz6DYW-eRDL5ep57l`vMNMNxfmvM+R;?_D)keoCFV0F%Pbn zmY_SEiC=W-Ho250qh&rS>bCfd)xXr?o3Cl6ApiJy9^53N&TI99YnRv&`x@aFgkZ8A zu|yy?E!j{_JU!kW>OcI-l8yy^I7nbzbOli-Hn}i!U{0G_&5$Q7qm2OC{_qh>T!}%z zED$~t$~)CS_))8bB(8#Mu|%wWDdQ*jKrp})LAEnP7 zNuJzGlIbgODR;S1WcT8mCLA~X-$=SZ?!sTzjpV4_;fFBa=$UwsW1rtpK#^wu<=qn}>2O5q6B_v*J&gYgj*_Hdbr7 zy+_-oDwt!0z!D|N~LYbO*R&|05Vu~>Z3=68WeoZv(3Erktz*5iCQ2&J~ zyaQhyE6bg$&zlQ-hYjOJ?+oTM{6U-1jkAxVCKFqXeq+LN^wXv}yNQC00GfYbuN#wN z6?n=Hn#Q@|#@LA`R~b?{f>~*4vvF_y7M`$|2wxWnuxTLE>O9`uUOUg8@zlpNN1lw9ubjsnwJ0x??YMZlYzZzT0)UTY129~5bp_h9>H;(j z^A94BK^ypE<5{zEa`N|YKKqwHX@1^UIMo24Nbf1J_k?d}O*Z^?$y>iu{l>@D6O5ut@o`78L!HIj~13PY;NwzZ(A7uo7`#^$S7ol=fvJ;Nj1)&8}AJH2(op zKteTuu~|Y9V3QcunmvWo*@Bx9b+G+6)4KN6@*`6J6G4jU_#x|?ay0hBDYmqfgna>P zxaJ(fF^3dkg3~QoqCsCN_=x$l;_u#3Dx+X_U(Qe@E^h>!i+4# zF=}-*{~bBJCRSk_w||@qK@v-V{5?6!T5t#>3pkJY0Fn6VXOm+;|Jb|c_1_dJ7)-#j zt(g5QenAF`P-y}7yYd1IY0IHL=uHV|a?m2# zEetkeH_@6AdvMxbIiqt8XIZ=Q(FsrsKczh5d}I5vP~#&}59 zGt#VkGQ0Q53I?fT3%OL)f{)qZ26`X5+AwE8twFFvvoW>#xxV@v2NUM%3y7~R+h1wf zL2%9LKep8z=NP*+r(hMTQIOt}g>xW|nw2g-Glq9|BF+?!H&lUUD^r700P7wdh(t)Y zj|Cd_AI-9_(k_yFvvs_whs_;iEIJv$MaYNq(Qo`N(bDs>Fts9&jUI#-#>GjKy9Q`~Mp%x#+nvR(ft6Y2 z?C~Hu59OuL9k5fdkHDp;J0o_`ghSU8WH$d)>mD-M9pDs z?bql2ge4W!Q@G0P3FAQN^6A)Uj|R@;as)s^T!^4?jn?2tDXJ(gMRSLSzJKkz|Hq#% z{n3M5rZ*rC=DiqY-PyS-2Y$Eo-QO;G6aQcT|K9o3Rr1eo`u~AFG`|;~U4j1}e=>=L z6XtI+KsyT{=Y?bYnQ$uRkrdXN2L&n~K1rx0|3!ccS7!uQU+GYS>ci)4`Z)P81)1hw z`OPNl&bhRhq9#Y~iO{z3AgCfn9oAxr_&3I1s)h{`;tw{hs;&{hnl*@&c#;Xb zu%O2${?cMsG&!pWu@~}L0^|{46KmWAU#KJ3Pjtb4q3hh0Ut)B?Ql`I{vFF7vZe94| z&iOCjKlA)a{lf{K#+=QPrVeFYIVO{9`^dgv8MR^Kgxxe)o7sYs#q-f-`(57cD94W8 zIbH1@*T5vt?%FX^h5Kh;%>E^P_9%_N`k%!Zfk)FcyZ+rtvq!i+m@o9tOv%b`G%o+` z_lvHbv_*ALI{1)A)PEbdT=Cpj&ZaIL-!XkCW&W6dm^^!ojEkzvBcv=I+Avma(~VgK zE8~EHNdi%Us~88=TLNB61ZE3S^AmFc4o?h6ab?-jyw#P)Y-je5fA6RN@qh07=@+?6 zoQF$kY^{5ky+kzm)kdTdScJlry>Ptl;YiKhiR{^nJID4q0#+%e@P{xQ9*~BRO`FD| z(ED`410-BueXYToN9_fu%=2-6IJ3D<}sQ*&_J zEUgllj6_Ai$ma3FoW;Xd2COP#voKl$&(X0vBcOcxWc44ut^OM>EUD}6cNNT^sk#0C zQFY&8dLCw(=>ItXY$3%-9LKgSSM`ym_ujik8g*G+n$h&$dzEI?CCip9TXKT!z~fi^Xemgh#xrR>V{ z$J#$VJO0%hr{0{cxO^OdFR8^o?t$W(8zZi5Big3x=Tt9-IL{15yBfqKn9Q*FZ(TyE zLe5v;Q*!wxF6L1SA`e^KrM_;*GIDT?tOQE`vWsQXb!V$`i zf>3}eTW%>?IjU>hJf5*_CU^T>K0dH^=E?Ex1}L;_A#B4AEEDFvlW#E#D8$m z+7Z%VtCq>Ghsv}$M#J6jFMac$zyIYw{qCMSZB{v0$AIw&?kK!@_(KKj{%z5xK3e$% z=Lb6+#ed`<gW5*ER%qfEQuo4Q=IqJjxu$L7yE2z{H@!6Z zY+qgbmv0L7A8X4=FhXrQ%g}eolJUr``RQ|er+)eUwE2D8XDWBh)}$}%mSVh!rK!+|8~R6qqz5cq(9P{QSnM|?$p^`w}%W; zp&YtwH$I9r!4xii3?Sy}B$O?4JGad2mJ8A^9Lrrfp1%Bi^0~uFXq@K``$@{;esMU- zcE9nRo6LZQOT9te0m&Gx@yA*d+*hSIv@M~SQ?5sd8_6%dGI0M-e(%>G{KN9Ef34s` zOK4zOZSe6MDKQCEg8_0A+^u4Wcj>iu?8=;_Q@&rL?w~lb-FR#uOZP$MfURV9??WUO zlV!puttU&X=wf&rSBlZ7u-~yQ(5LpT+5sDIbStJ6Yw@4!mthvqNv@T+C{J{4C#ito z`33Pm5G|NqcM{04VE#nr_+ffm!QaopiAL2v8t?SO?LUT<5-?GbXrNgxTs#bd5a(T5 zn>lWU5~0AyXXHw#3*Uy}*m1CJqKOd@>S_9H6Y^@s)!vkaogjULRrSB;CGs`Kaglu}6Xuh=q#;FsqoEw4{}?}tD5gCG9o*w?ODWSlgTMV=s4U}m|einp3a2-uaQ4@^wwCU2=h63XL{eQ3G26vbnRgm|2KA~u|mon+okr-8`~8^ z;I8zHk#gS`OzgKB-k8`9FI##Q_Cmch;lLdd>enK_1undOYFFB@ee$LcG8+Nbq4(SE zVx?o^IFUQK+qyUDHNj}A;!a5f5sb3o28A>+GUmTVL*pR7(0OSSczs~DoAS5<-NjLm z_vL&0QZP=`Iy!~XN}32cH?$ipjABD;RN6{qL0(`-XpuLaQWcaE-MtLb!Qu2ZCbnpY zT}VXH<}+h)%dc5|!rPh2@Qa9pcFbHdK?haeCW3j8$-O)~V(8SA{ZQfUJC!g#KD`u1-5&D{_*o3avDQA2V%b>_=G}X1bni>!xwFr^#kPz!@zQtYOE<9hr#h;#!>g^vUt!~f zNm@GqD)1#tdpRX__Hf41zM^w&yt&Y%1^mRkpuq{>I$aFZJ@VeHXt}vNihsWkz>S+Jq<@f*mw_o|AU#ogy6mJ}otbN0lQE0Je$z41oaRZ|O z;4)qDg^ui{W1a$Dt%1^X(4!?xgrWhFT!cZG@Y*4d@M?=u(NE$(y9r@miBA3o{Q1z? z4gS`ZLl085+F{bSZLrp*u%Hy3o@TRI)`xJy~bsZ&c zvxykV`J<=Pfm$9G&(mX?G(j!Q2ca3YSNn=Dp3>T=^W`kwq$+>0`cu8zpBc9otkjti z4`ol2m+GtiaE$z={k1QQf>2;DWtZAW+fZTG_itBuf`I%Sa~S4qhKMdJAp660eaYgy zPa%1-S<$YNiA#N;6gq@FV=67SV=ZDTnt=klp6W|yaKz?_>!z8hF-rR60hgkW29y^l zjrczs<7Pxq9vU7wZGNZkp;+R-`d{+(DZ~|Pp`q>P3x_t2);!%`R&lun3kx=qK7RPr zyLa}za-n3U1Fo{h>(F@m6PJX`n;V`_++Y_F^z=v=7SXSnDd@Xn?mu3kSvd5@n9lo~|Z4%YI{-CcLbu%r^hpql*YJzKhp8TGrtxzk|p zaPSBd@=58q0(@ar0oX@rD#D9G7(Pn+sc*iE4n$2UU!=^$R~Z)C<2=U( zf7SZ2xj+r_jyyuR{Um&hO$vM;{{-wr3aF3*3^-VbE2~)F1OV7yc;sg1FaGuK{>6iT z{OX^7xAx*;!(Z^YOEl?R-M=Y)?4uRyuz%UD=lb*#eb-~ zv8hU11t`&=Wuj{usv?Xr7lH|k(oiyYv|K6v!;v<1=dfOs7YsuI7X}uwdaN@WkCgjd z9A{$%FbEm~z^q38#czR}2XQ@|BKTD%)Wn@>g8%wn1;4mgzHPQLOopf8jMXWUxj}8j3VG0qf(ax9`zzRa<(-y^HA`7Guf33ks2FilJ_kQq| zshhw3jSJuX!p`gcKrKk}!+ohA>)Fnh?GxRbG8d1gM`S6*|Pjr_hPajN~IrL0#?UM;j z$M(+r9bqV1@N{c#WXayV#yi99UwonWXK#quCIw(64TXC_A`t(R7uW^JHH}FO*rkKH zx^0U)ljirOpF5GWayo7C2y+18LRrfz9`cN(le2s}eg4Q=UWof$5SuLB7|XnzVFJne zZHv!W-56~D;POkq|8x8AUr85y5N5(@Cs)PQaAg?QYNDF>iLD>CISa?OPwkeAF-1Z5 z%J>-Ro=t+fODl-tvJ5!grvpZak0~4u4azg%_VB3i3u=w}{KIXVd;_KThdxsZk+PLD zv{&g9hsw@(VZ5vJ)%;c@n-oKne2$4xPL@i>)^Emcxg3qcxTYGcUA@}1#V&8#Nc+!Z#GFSuV}-qjm$1&` zZyRk?06*K8E+?vB^~=h8x?Sv3#lKh=D<_PNCTim`O;jV`?=u%jAXG&L0o!L|iWDbV z3gF945HVD$PnUTO2%u6pjnI#hgf)Hf!ck~^t!I>U(ezBb$P{_98HxOM3Ds}jM{*Kf7F_2%JMSBbeG68mmX z4t(jY)nEJOz}Md<=u-nAKco!rs#raU~)NA0B$vkFv|K zwg$N+cWxgsZ|$Z2;h%YH>RX>{etAY-Hc}yHOP(Z>AR;X$i_cdQU_Qmgi>u(?Y^B?}pU$uR1 za)*I6#p^)qhWkG%KK_xaCpkZVyzx2YPxue=Kjm+7Uo9#o^PlDyM`|y3@L(7J|9AZ_ z=F|M94^)x;Qhu4MqSnYM*fsp43MTged?NBMo+03>;s2j-c<@6@zU+A^T{@aOz1LRX zFsU1<&zan7DX`$b1{TQ?weX_(Q;dVwx5lV+TTgY~)FB?B1`5^(An*C!fEY)JV;Ae5%s(r`+J7ejP)8D|4;JoclA~xd50-VzrQwL^Z!ILVk zJ^T&S&pd^m>PWEy&r<{`G|c&PEKlkE`CI(TggdtkK-DX8Z@LB~f}nFC3gU7PWR0O&wb~E)nEGD+duf; z;xB$KX}HOZGCUbtVnfQuPHz=k2)O(q7}iU$J(Iw924+I&xFG=QZ|`TtI4VWUz)uiJ$gt+Of-BO;c~wqRtog^+!Yvbh|DdW{C&`+#cA! zn8WhJmoIXckC<=LhjOP;+QBgb+YgYZguOErL)GQ3iq)Q+`ID8GN6IgrKCekzxu$-AL#u=E*=<-f83<*$EY`1{~w zKt}=siWOim6H#K5sYickOe)Xsefifu^QRB~;cx%tpI3k5)%2lq1I?#9Q#bYIm0#Ka zuPWAA`}J_s#!anx#-qu-;rx)=-zb^xdSP(yt+CoG?S-@Z!n)tGp8m=$J?JzU4F4&A ztqDu-tIHbRX$L`&WIEF&g4DrUGTt@VKQz1~U`yfBV>E1H%iD)NsUx9KYjmz88eqM3)2R6;%%y*)!3N-*;Bh2!DUVEFI_o-9=u^F6KJE- z;J>OS=Xyu^g#{#N(^)t_I7LOvhYOZ%fGtv9nqj#Cu?_-x9>fsNH!LutvA)@#i2q7x zu8($nb4?Mkohz8XxC#;>0)3p&iA`2Z=GL>MWEoq|rf;l_jgtG+Sp{}eax{D6JwbbN4pDm-C9(6!i%gJh&eR^BrvTb@45D(tzDP~RW=|~-q{$wt)(EP zy-c;hz$eyVb!0oqYF#D_dinedr%NvP*SOCS7??_c_@pKH1`&lpEp{)x_QT!{H&cvS|M+h%LI0GVd+xzyV)a6s^0WsVtIcxU7&TG@u`ZQVMznXK0 zi*wnGpfTcq*LIOVc8axaQNs)4P;tH!j)=f`M3X^H0VYVDA8AGYF^RCkU`Lp2v?ufH zHoFAH1W|va)aCbVZ&l{xf!x`{oBGOJ9*Coa41^?!^qq`AlC!iI%AG&kmO9alT9Y<) zEOX{q-uY9t*C#8lb_@6@h$ukl?x8G$bd6@I9Owvk-W;yG(NlAESghbt@A@})LUOoEe z3u@ytpT5J--vnP{<@(fNCAMTDFvNl$pMv1yI!T$?=ef4x()Z>fL((`n$zU8GHzY@G zkN+8kgbHnDe~55xSe|JTqOp&FRO^(lA)!w*DG+wc@|>9`qC`ZzzQMnJe07XpKl#1trNYA^MZ8KRF>cOdRL6)fNq@&CunAB}*agZkfF-i%XW zf5b>(!9wHW&)@!ofBx%#`IiUp{N>k6XPV7bH*}?|#Ijdv|5ep`@&A#1n}9!zcT#$* z&3`dAtIoAyi8Fs|xYCKhPu0cPA%mQ)GoSez+cy>p>N@x5lm;s2mbSik~0Z7#qUnguAMiNvDeI$jWH{Ipso z4#G&Nx-5JjjF67w6vT;(XXQAoxzw=(A=4N{OgdCNd1OO-8f4~^t=pJirH$>d9KiQvW3cPNh;FAUc z{ecmM>K{~xunSuGd@{!f z*Y2(&8+I&xCZoWZ(np{avJ6TLf|1qp+P`r1>7LkI7d)lma?ki!e=4oh@lRjeK6a3^ zw2GIpza{LCwHJow^enfu93nMwURH8iD4HECBVr#`>?31jv<;gDHieyzplJ8{nKy3? ze&yB94_;vDS+?A_b*R~{4Fn!lu07quUw-}iZ+)rvgDXQ{zGWdr&ddo;{_v}R-MZ!9 zwr%@FPm+|!H#>sH7-wUQ#|lAG{o}SJq6l9kD5O4rsB`OwI=8CuU3IP;Fh1jm%_PIF zz0nduzzkYfWhQI#%lI0YAIsfrE@mAQqYV@D1~`WKf+Be{+9U$7$v*u;dzyMfP_D|lmk(b3Xy+`=Fdd594Zz?8P$qc zivOJRdvlgr5(_JfpzhBCUdAcTBFO@0LT^ZWI1@7|ofwjZ_sawkg!lzWauKH@tk6Rf?-;J4=v-5=DL~Tuw@Y0ILky|C-jpguzO#UJ5>0 zDbm4cg^6MKLik<^V4=(lVl+TPOjoQY-^6mXnMTP%HvwC786;-bd)Rb0zp&WsoV+$| zGQMuqdnp9+8_HN`>349Yuy-iysXS7~DoD3>zBq*Z2JJTpPMxx%x12Rx>d;;S+lilj z$1DthM%k1++-N{)=bE=^0&W%z=g9#X&F(GL-p=fb^EpyZO=e8M4sQG4&d3G8(g{i{ zSs<|;ex%;}Vtodq*g8;HJilw`3+KQ2_rLT1{OG}d`1|kITse-SkQA)-%!;c=eyZY8 z`2V`YNg@8~2rbbW^fKWm`}GyaDSsNObJ`t5RRNt7X9`!EJ!awfVXJ{54~hCV z-E)<#oTxZ|meom!J|-H>XWdq!rTnN99TneDlu8* zFNs5DI9=P0%4;IBSa;sX*vGXOfPD&9kIww^=d%}2n|6izra$|Ue&ogtK&OtcUlIJh zS>FffbT;RaGevd~Z0v5ZEXGbo6J%DU!oHpe78m{%C{KxQMOtx$L+L>FCpx!yJC&;g z2yYfKP#NrA}t0zkTl!ow_I>a}~3Sjj(~b6{QBN=Mmp zhl0@Ms$sGHN+mBoJU13jIN*_Bj*Vq|E^h=<0WC~KzkF!?!`A4u?|7nfhwI#KUtduc z%^yowTa33d#`f9Au_j@|i#DZN*S2GQYxc7?nYM37I48gn2}LtLX;!?IUmQAe@8y%P z-$R#m*8~x|EersW%8tHubLY)PvR@=pqXGC2NBy*!n)I3GsvCVl-JHlHUgnD)%h^W? zG_z13ygsu|KFm6W7<&!o!PP6S^zFXA#CF~wRn#?UeR3p2BCzCFPE@Kvoc6rDfUeIo zli4X#Wm_YGehLW)zt+zQaRy>kJ(Op`C8C#+w?@fl?SI8{5d+gwoK$JUOhj54KMa>} zjV9}Cc8Dg0UMykR=f9kJJ%z-rO5A;W^vJ!72X9~M_~35Om+n2~g!8^*PdZc*i$x}D zBE%u~5QamEhinR~W4){TjoO~4iY??5JV;a1=Asd(yV5)L^PjrAh_HiFs6=I za{lakZ|;Nt_MN|f@ZgUh{PmGHdP9ZOkqU*z-1~6NlOL*j^0`wPTf)G(YdGS+N zp!(T9aWH8@Gr0S?!D>Z|>4sG=)t64L8ALM(s#^&yFhK$OXdLs$tXe2fYz@ZqjFrLM z-3O|PxncvaJuKjto`S;JBdYp!-8!S=_ECkj@d1713^96`eTNeZCM{qZ;;#tONL;*=v8 zDUB}-m0oSFywR0)?m*7UA%oH|Ad&DYF{HjP9H>f;6j^4!RqK9M!u3_=(G zz0>H(dL9bEbjmfy_?TXjo?cqC>RUUCbAeWCweB%xZN;8WYAcVzr`uV}Ciu<}-bz zQXwM9`|8k7RXt$^z^0an zX@WW1|A_w+`*z(JM*iP-d)&|#+tYX@Yq&OTuxwj*UTph?|FkBXe%kW|*jIJ0xjmx* zt(jWrK15g5CS)&fLP$AwC7#k4}i)mxVfl*^}1F%YCj@kyiY7 zp(0JmszG_O`T;3!C|B+ie0(4Hp~4^ zr2uwR@(1tDUjFs3A&Y{lz;t3-tdHzP`wu4v)wtu4uDlKXHD^D#Y%x%v$K9-eQAT6w zq`oG!>VP0SXvF`4!raxp@Big*{kwnq^Ra(-SFuez^)NuGHyitiI!qFIyp8X1%mKqz zqPwj2rJ>26`{MY|e|qwl?o);;LK1`2sx5O>#h1?%UT9-gYKPauCsVa}vIe1d&|f?A zBK{lJ^p%{rzj*A;)#BA|sLK;QrH^--g&idn&09Pw{>O?vk}DfDZ06;n5P*65Ct9+y z7h1Iv_8>&kJd^iSd#P^-U_(XKxf%Tap)=1>P93|yVC8GdU?8`X-+1TbyDR1hxJ=+# z^|QO)u+n3iM`PWK#xjTtW@BqkYJ1VSzuZ`U7{C55F?mc%g6M+ix2|T3%yxZUhiid@OyW9UgS;XTua5pQB!HvvMYJr>3jyl>}Xu`=7wQf1v4=)MVK6|d9p9w z3xv(c>Dlf={1Y?=6Um&JHe%VvElxi1!ms!Kt2M zXs|Pry+ha^72%>-N&n2*D8{V2I`!t=lW)9n;MJ>Dmj`)%YHB1n5w(!g^WuQ?p+Exl zcx^DBO(XTHbh{nBT9Z&kFWnPSm|h@#dQYgsruP{NL|H3r21%(9#?D8`-r^+ zPG}kI4t5WMV$_PR@Mp#oUVkI`kQ^~Qd$Ca%&z|RRP=|*ci$eNRHw<#E57TB4B2BS$ zN!G0niH2pQLH75XOe!*FYcr>JvVhzDQvc4IUHm^20Uvv+{@@#vdtM$QB38#r0Xi}w zDN!qwQ$6`E3BjuF;<2~>=xeY4!B_s<5C7qRKKRkxcdqhki}TZ-Rr8tCA1ZtNUstYs z=5(4qjyBftcSm1!!R+Dvwn{T|*6Ur~c-;suFwxWY&+Zi%+z&&E~3wJdhMCA*I zO>f~gVbM9#m^Zx(Zlgjo{ipS8YmUS4;bh(Fsgl`)@`ajTov-ZVx39sBj$p7v zel#qA3x#U<+{w!GXROGPIIul&M7hJ+3%M5m0rFgT?4vJSeE!Ma9e8>if#74B1v_+@ zDIrg~VzKNzvP?&nsiLOab?W>R@P(mgR2u1Wpu}1?M{JRkZcIQz2590-_ ztvOn-;^9gm9oTgu_=Aj;=t3^I7---~C~mCzi!Cr7#BCdomXLZ$6F{C&&DiKYQE=)r z*V(^p9&A)92wd=RZ2U)i(=BP*cW1oz=E-PM5=(?3JfI4t6x@JQ_pi+V z;uo&}?w9#XXs8oAf}?#F{Ixj{A-Tq(9J>6gUmg3(8?kb7M-zy6QZ^xw$ zlzXzTJp0`7iktlvHwG(T95B2CrKZo<=`>lTVXKxW2G-2<`U|Y1 z5~583QYQ8*R;i3_X4%-c(@s5G%hz_tSOm|V80*GiYrIw9xNvMhaweaT+1boN*t_kD zZr)&fj#dGp*AEve)Dyr_DgqLRkhG4{^xk5VdLt^p*GEsKnjPyYoGZ}`_@JU=!YMTu zT|TpMnEh!!a=6!EKh*5E-yHkOD+}Lzzxno%*Py2$`-%-aoniIBIbZyDgtr6HL|5k4 z83NlJwPN9==bi zRo!b8F3SWxb+80Q$|o+gg3f%z;v^}S0QhuoT5O!*Sl&a-Sg3RnnTr=YT*fK0d#oaL zHX!OgzVxL%;1yiMv@&apkhv%Y(k<|w=3Yq|EPkjsxg;wenzV-(#<@#FK_k4iT7`xe*6Bh*I#LV zX?f?3Nw4477iClzuze)7x~|@sm?TISI_T$UL&i&yLcN`eOUHabo)JTv2#(>rE6}_Z zan2k+UMFkTksOO%Fk8^hpBXUY4xs^&3mgnSukr^~#WJk*+Lw=F+d`_HuFwulRah2KdGVA`fAp;>)F3?zoX0?%1NPxJXSkw8{XZOK zKMMl$UlU}njr4#!XvzGZrElK4|NXE0@sIxTuOIwyGq%7J z|BC00r6a}5NAdj8M3aZC5-tmip3WUiJF`9G+(C`13)|>KbtDDwZsKI6oYQk< zDz{uY@bX8q?HDpnM&yZa#*0ulgWVCX(MF$%<0l*8!7s61b|i-whe3VQ?V0k+ zovsZw<9Y`)OI2lDx*V3!Y%F;f|5^C*?^-($Rui-zz|Pdq-Cg?5*9L#)vtRtXKR}0O zhNch-EmD7ugtZm~)_xg+v}360^gHJ%an!mA1#!?jbr$Qoi)0fy<%zxmoSCrwnQh|L z!~8kzTto7FRmO5CQ#2`RKbNT4oIm+gTOsl);49Q3T_v_fKhsf6#k2qInKNHnam%Yl z+!Vq{@Id+s^H)zqa9B8vUPur`!Xx9X8%i@lj>y@%-Asg6UYOl=hpYCZEe7u8Hp`>1 zeuVKpGq(VCVj7OuQFn8s@IueY~Hgiu|(_{zG?}YjYbT(K{?{o@&CmA*fHLSA1LA}P`!BV1_!z4`l=bT zPyM@hKKn5s-$Y~W5z5Sn#vx9q9$ zNuJ+de7UF2W~=ipn@2;=6q~{IRs>CJK0KB&MHbym#ceWRp01J zo{wIP*%4y@wz0hAu@c(>Ak_g)^Ns0Gd2T@3%~HAx0ssdXp!{2O{?N{sx~LIjEJEHJ z+O9Id5d>q;oq@w|jzv#IJ)M{WG{4+`?5#PUR0`_5dAe>WA&3w~JqutwW1?RD-}C;$ z7yk5HfA-*?|MbECy70YQC+yL$r++x_K_v zyKwjqN1%y4sQzq489v|(l`S4Y;}=u~fA^hxT>Mv!_#ng(a~7?Wuh1|C+H3nRVSQjO z3%PK}nMhNF#qzI#+?ah2H5#cq3C=BNHW-&Y^>pj@Cr+i9QjvkAk2G1zDR%@3Gd2Yz zBO=;%N3#IcF?KiJ1%WD`;OAn3+fCTllIsPmm{B7U={xO$o8mdh3}L+0Cz#U2hrYy2$%Z!uiQKJ!SbFr20TTe31(>ec4G7Ov)NN-IG_%{? z`cTJ)huSt`#&X`nLE7F`mef(Op*2@cqD^C7VI2I?*3GP&ga0EHT5AGJA8n|*GCJ~e z_toKI%juk|M_)b8iIZH++m;rPvGbJD^VHE zdNz$@gTA$0c;L>efSIw-5Co4wol*8fE!&K(ZN_}~6b>*vDtq&QLE#~2vqwPV@dkZ- zB7;|jTI0hK{AG4aFkLo`=yNXYPZoF=%2VfyvgRsm33N7ynsJm=-vfF zT@+jgHj&=nniA-Q>l4exa+$Qby3FO8?4`P#b5&W3Ra_%@)I7_sc`{c&B9~>)oiI5S z@Z*!>*yhR%cc5%^{q?;mniomm$i_UEo-TQ&8FVlHH@!4fapeqkYUSk-u#Ei61$5=}%9j@~L1$v2HZy$qA>Z=f;>8oC%ctZ5 zTD;oJL-j9AmtW|^kAf@($tv2z0Ep}hiHc^iu zNnJ}6kTF(Uf8oU3*IxXEzx$7W^WaCn_rpIM|C!Yk?}YIf zXyBU<5ippyuxDdmiSk?0WZw;6DqlIRVvku>f5DcnO5XU7wr_sisH-){hL;VevYu_* zW;YFmnjoLlQ_qYPpYxga)O9U(#H9G1V8MT-4AgGuEEoUbIXKKgr{TWNKbf#Mh(P9j zDNpny!;T8mTCelu2#DXc16w`}oD&3@sLID$E?2faVka>lexnV3r+a>jUtizxo`SI3hNi=#m zoLEL5Z{g~^mCzu_feGhK0ap6Z)5YhTs2PYEtFN9xWim;d80kNn(ci!YrO+aVSDJ~e{}VZoGfZZ`w`b?lUfGg8lmeofuW1XW)aOYNr{ zRhVuQ12vh51nl(vyQl8I0h|xCbGk&>i5*p==EH)t~z*e*Y`EQbi8=01-dNPSoc;^k`)_Rvx5sqxY<~6=_3ZPtJ^ED_0?V* zZhEobI*BJHwiuOSSV<^=8cmJ41AIw*=Eu0Hi-I6}f#>huKJwn(1NUzqedpfEcVD;d z_sCmUpgnTU`q9*wmX0-+UbGnE+R@kUSf_sa?blDd{pN{xZ<&B=)j_`agtTu)47*;M zHJh;iJvgr8g^!PAJ~^IktX#TyX!q^zqSfc&U8b=yRT)IEX{cD~J$CN z41*C=tX8)p26VG+vS`y(4mC&a(yrY3=A7BR1{2j+S`WTC<{J$Kw1=7%BBWW3h|Y-jSu-fY8A$P93vA&=QX#z=z^0Ew2tE-6-Q-5sf*ut*(hqVo!qH&&>V zJMoH(XSD#QVLRwR0mTfIc-fiLO?h*>>B5Y~L-9T6D2ersBjx2QM>lm9>$X@Mp)m0R z@{=9?4eRJ@)aP9pp%*@zxxK&41~K0}(YizLxvjSBWTpNhg9Vc&0-W09g^H~+)k0|ce1p-sSHjUfh(?-I+b~(b_LV%| zSr8B2pZ-jLRpa%Es+C?8pqM+11Xf&iZEV*olX`F$BvOrjhkl=`*XYx(a46HRd*hdW z?Tg3XTo!qrX|LJPQMt*5H&oBqDtrDoeN)+`p8VzR!b_d&2bIT~h-!g40DnnjY|>(>pX!2qZBQ zjd^HT4}~ci_K0qAC?C;<2FjJ7+BckiaxiVjVsW5wtl@fN)d;_rJAd@8bKm<0N4pJ^ z^=^6Z3w7UH<6p$-=<(4VKo8YI{?&tCtwt;70kk{u5fLWy)&HOJcbckrsqOiRUx|?Q>Kga&NY->Z7#T^2jTC{+Gr=G0AXPL zrO}Gjw%8!7T~+*#X9grSottxE-}+G||2+9~t?n`(3BX~hQLX;T{-o`T)p-^{E*vqr zSUW7OGIMPTJ;+d}Y$lG_@KJ#Yl`>(aU`-)||-eZ{V4iwg3n{0XeoilIUYrHg; zIft3w`1E+8a%IzKhU&|T$xV}aJ7&rmayGosxn-cjydD)FpRM-V2y0NoBV2mnF=L8< zemJKoCId^KsB^mb#noKw*>i1b&&w+Z?_6zuagG+uFT`+sART*?;gwN^GrWB&H*2vZ zX(ErRTI!T2u{HGFN~XN&qZ-L=lOY3FFTwUPF!QH&=Fiq_?axge-C1>^bLYj;lDX4R zj@SY`haOqt_Z_lx{gspT*IEh}_7zyYJyGXf?0aP@XATNfnLXc_v$)Ia33s^p$O0CD z0gC{kK4N*F*U;KV0B=pyrE5?E6-+c7d9mk}|MaCl`i$3~kEVgx zMXvhVex?5Lqe;wv0J#)i!2jfd`lcJ*%s+D`cUr<#yAo@85qnbl$`W=585Vve4;F1U zLTyW?5b<1AeU;1~u3kAQyvraw_GJO_pU&4ZFT*L*b8#5`EUCW=hL4<&xMIr8%)v&3 z@Whzf&DFu=w{+=v(bTd0$w(y%^2b|J`QU9I*>5<`q6!ei?afR?+oIg6y4WhS0DRyx zF$n0*m5EFWGRJq(AfRq?TS^+J-O^WS^R)%vvW8Xf=tFCVTwwUilhe;5eK2wq{QF~< ziePITz}wAaRtkVZU|Oo}_3|ckSayNUj+Y1{B8+6}>J1)F4_-|UISChTjTnW#TR`<5 z51V*!zZ{_wKf#DL0p>)7Z=w;FDeRzwu!JNp{@Vo;g#WHc1e|$HNpv~@2fvTQ!=11D z{g+<;&)?oQRE2B$$*zKs7_=oP9NP-R)Xux;QatClVM7{#n3S-OTZ4~$l@9zcd8v6T zU!B<+oqpJl%$7oi4Sb2$l#$HP^3R=63exTctmIuVG8!xk(tdA_pEtiWz30{#!nr~# zAo|`sL*xs;`?X8I^V8<|5(=K4*_^NsB8bgXNH1fxYHz4ZjC9ZDS6}VaY3{l?U3Yb& z=Gu7q<=(1m1Em*x^Ug(Kzh$;qR2R)u!lJH4y2swU{`|ewv!A~9-k<(K+0|~9C(PW- z_B#={R7!LEDz0~-_;-JZ?CoziPE~;^INp$(f%?-Hn{8g$FqP+(5Kh|qC*U}- z7(^+|Bxh}GKWx2%%wjT|H+M?I$X!QYtm`*b+|pCNsiS;zPbH^l8ddxgZ(K40nAj1(t%*y=J?D5^`uE+MF_6Qz&CGIc-& zS&6P2$#{Gq4VlMEGHbk^oZ9sC7z6)&JGs=!k_Dm{35F4;Is^&dUUe+Zs?{DNSEalC zlDP|~Vwc}A?P|T}Reia?Fac;}(%52L87jHZXQrGrcM1`d{P~IQtzh0Ky3^QS9DVEB zv9~VU5g*0>Q01n{ik8nW=PcI)wd^C?GF@O`$BMuD#S<<7bx6wGZksMu;NmSpKK0_d zk~9vJ{`M{!tV%h%Y~Pw&Kz$lL+nGvmCY2Fl z7HpNkgw?=d1R*4@c|_<>&27d1H~z~v{^G$u|J{QJzw$r-W6$SjAW@0=X0}Oa#hoJ` zKez#4vZK2k{*%;G2`Arqts8GAbF5zc-*vUEXnLO!FeuO1*UXpsPf}k#BhaVL?x23M zG0m37`jyt2l`|lHkP+>_K|tn26NV3TcVmC9{zz2JncE$FOFB)=nZbfsRlvexq#mO? z7KE*|af+*&Zz-NQRyuhsy|3Y!Gbxt#t~-n4p(MqFcNfX|q=?S8mE6w1*oQ2TC0GCaNPYO8ikQ6oza7oIw1vO^STsIjk zbfhDNu8o65^-s0sBC(T1IiDtaRt~wjKs{o6BD`z=1LQFfbcE!gyGV2AVS)d_BONLf zX$|36rzfr33u2O|4pOK|#827~vok_q z2!r~cC5sto+G5Pw=$GkCm2I&{Y2~c#w1$Imk_}e+BRyFJ#zAiHt7Av+tq_UiEFDH& z)|kZ~W=6J^%J9ySALwQ+O}-#W;0AM@#@&&yH3%-WhAW zHC_MWbnQzMjW?DBe;{Y}{O*8B=X4^azzPvtyk$y!?Cpz(UOvaAP2M?q|5ncV=N12I z)Gbr7_Yj<7gn{O9@wdM=@b%jTD+je>a-XWzZ=zgE*=7XW7t4K>SvJo(GdXZ7AE=fm zck$%iAN;1dXW`iO^f^x=Ewbz52$Ru$G}#k-p++A&*|yUcF% zNcGj0s*5Mgvw%@92`9>cCTsbS-DKORn?+Z&c3c|zaW95HiQCG^62~TM{1ATtDo8h% zhUJOAG{}-r&kNB`E52}EL%dl=XY^?17b68`$5;Vac7Tp>0h((DaX4eK`tw?!u9hux znq{-aJ22zmR(id1Ql|MC{8cq)Eai*%dg1g$uG*mK(ZK?<#fk>ro z)QNyHY}KSA3jx$v75IYgUiGeXOzgD@KBW7U25@6v?8c%awoOvXTQ{&(fe}j_db5gF zS^OPDk8yt7QyQopV>_+xm8W2CQn^aL@Dg9pA_b3~L@KOUGJ$r*BZ3X;l`Q^s`{o(1ugj-m<*&_`k22Y$x60Qk$vgcYAHq1O3Wf*+8=9z-(AV65_Teg6Q2JW0}*A90yk)Xl7TX?OKCm44hS>kE_>jHkVub4hdL=A@0 zaCmD(4Id2Npouypnt+eGvS?>MX|2qev;>-zs>u>C;gIU6a3Kr+m}RVpJ+VYMAyCQ@ z>S?>A0QJAQ2D@@u!+!yP)(o7jZuAWYX6_0fZ;j=)Pxh2q%JA}k`X&~HSRJA>7M&eD zy8=0Xq$lgCfzq0r18@J;Z>i!~sR;h=6v1D1TZ{k7Z#gLM{K?|gPIg{AHU-!OtX)H! z2F6izIlYxDZHx$tS5B;lN+G@UmUu4B1vCR)ZTHK=M_;>i^xl=KYdy}4xS^xLepe^w zFCA;TK6Lio>oGt>*e@P-sy1 z4RGzc@^K93<2Av`j@(@t`}$ja7dP}(Jl9ik<3Imw^$Yz8=|Kq>psjNyS_XkMAo^fe zmfJgQcS+0VFYbGFGT^eFqGR`0dOmxPW!>5u2;SdpbWrps4AWvXXIues&@)uk@ zW#i#f1F>vN-K$NbnL^$`m6R@p9oAtW6ogWS$-7_S$+@4GMdXXIyfiC3RHyUuZ>1Dw za_a3kvEEV0%8c5(^_41tWFiR85{d*LpAn(COv!SeCAkXw%9VDIf;Gf8NTRZsw65>t zsu8mli;dLG+olSwpD?S{i+M>bGIW35k!0Pr0T()71q0t9^r|Sr1umOS z?EXg79H~)*0Rfb$?2lO0sg|WzZqkpo?=S%j-n(5A(=~=@2Fh}l=jFw*V`7)-n8~l? z%f{JER?Q#Nll}q)dC8?Cb=Stvyn7ots%WKE^j6;RZld|(p5#xQ+e2>*oPKMx@ydzZ zrJc%#XQ%T4_*EB=HC}JaU*0EqnSZgBE4X;D=<0s8kpA(xkxUM^=B;XM%@k@AMB2ya z*|j#?#&hX;xrir>9U3^D+UCG9n=nVr@mEk;Rcrpz5o8|mA!)SOE-+Q7pba9%AcEMC zvhp-jMK@iZJ$i4IHE8*{&cfN&{F(SbowV%v14IEnL{(Yd@&N)d>%&Y3&_P2f41^r6 zv?ek;tV&zltg```V+&;R*@fBxHldGP%QfAP+L{h7?EI-wFfkpO)A zBKwQ*{vzFl_H!{6jT^3Z;PZ?B*&{pA`*S9CSuVVl4y7ZF0rIx)0?hv(TL87?rS;b$ z{IKzfoYgj#t@Z%sHlLY`loII2JW1)b|Vv`!S6|h&J29(99VzeP^bQjr|ZDROB zc1o@tg$uhjV~KMm8me-Bys)hUwsJT7lP&#)GG^(_DU2hw%uk%%2GXYpvlNoR6PP1} z;`19EgsbXgy~r>72bp%NmLSnZm9PqNrODcqVj&noZgJl!FdWVvJk5zUzzv5MwR!^B zQCWrBD?$5*_WLh70yP+eh$mWN=d88wcFF?{$ZcW^*ig8)L0}vjWGN5fP#|?s*=Q(` zaAcM>ZwHNoJR<%Zb@{c}1^*KRe{hh%t_S%=tN~%> z;~Pp_%}e3x2_%zKpT6Do#aC-zY%#D42I-pLX@7uG4w2;K=g-Z2_p_y!J29Lg?S^-N z9ipw2sb=2eND<|TTPr8HILa?tn_&2}v*te9AF2nqN6Y7~p8ep3{FNi>L$^5!6RsfK z2CJm@!cf!IDRZ<#uV1UXJy&~cuH#GhZ~x$1$Wd{I?d%(k^#@7gdk?&Ee)pX@7NA?_ zOH&rAvln*eiY*uSlwaPHy;zI80;xz@Y-+kUAgx#x(ewGMULH(|X^*-K?j*@_A7X~j zoev2=d*Zk|2t<%Eapb_=+1eWexy#Q7i*nT1u0C^x4`d!fd%)V0b&$6W6E)s`@wMaH zD-R;U?R{nLmH+gsC*Qe<)2IsdMD$t8LV`G0Ys_wRI^C(7olsw``jdTJ2pLAQ9_dYwHNhRJ z7K-tVB8WDD`e@g-ht6&?kx_xLFQ~aXRIt!lb*bA)uD?1`d$m6T_-bF_+-b2$9pXZL z+(Mbo6r4%!!Fc$JE{KpaChY9m%ratooocgexwT}zEob&v-n8xWCtO`>?4-$E>xa{= zR+Q=VM@C%=eksgPR5GqrrwbKF70S}zeI(c#o8L+s+@&Z=ejCBH^7T8^awHn zlxD0<7LK)*qv;#Q(!GEJG@g}HzJhwRJpLBO)wLsj{`5@#V-p#l z7}~yWG6kf$_eMw0XU+?=2@kz&oE#ZbT0zx7_*AgD-_vHRVEZWLlCOtK06vvkZ;Ra> zQdKxJ57mMZczZ&#vCw(WbI-6f-uZVGaiTD9(1 zpH=$CG?}LXf(p2MAQ%5<@3pfp|NiIy>w|yz^B?}p*Z=BQf98MvO8x5dUMl=wklgv@ z?yxv(%@F@p@J^9PM2ipNiQVVFzezqhcVqwu+o{9yZcgxDXp1MU<2 zoqtTuP{x7j5~YYjg=-TdINgDyAT^kLxlkk2Csue!ObA`sOLjC@!gbAeT+E35p%qGq z!j$*Mg3g}S!_Zme=L_dx1P31@FSUflW-+)um_4?&j+&XWn25-4)MeU>=<8~i0u*T= z9ok+5Ma7Rvx8$X#fTe2+KGpeSH;Dx65-tRHDqsEHm-6R3YA=seU2Uh~QYh*Wqw5!$ zy9!MZo_~FrdwJ8#^GEJpKKtoQF|Pf|kzj-d?Gum4s7?TXrmN<|rxI%l+qd%y5Zr*A z0-eZTcHsmW9eStu?~sxJzrbGU!}wdwkMuf)J6g$D-mM)m?b7kxcV{}k`1G3892t7T}mX(rEb7D2*@&B!u+ zp*&+LARuVT=BcW%IqfdM(C+!%W!MyrEjCU}RY(R%aqWn2Oa0iHWR^jXp30+^vSmAe zp^eB+--IEP5aSm~RWT{X!Uf+A=N-5|p?G_eQhu}wj1yfynd(zh4y4;yVkWXHG ziNyga+<_kH+h#6+c@@jH=IcyRi!PjiV(}#-2jfQ(e$g$qRpzk`w8$Rf>e_y!#hQC- zK(_@n(NkpINzTe1b#m_cgLJIQ^@=MUHZnt6#6ShSGWD^J=mNN!C@PW$>t#c?gOc@A z{P#MxvL~WkU`2>`QOx&pz7>iBrBTm3)}6eTOtF~Ifna4O7l8$hX3`F*h4RiFd8)fK zZK+B44Mqg`W&RXa?fS0d_3iwN3QHE-+_ujQrPH+HPiCLnV^f=1wh4>4jhPbygz;Jk z|FQcw+uncg=&N_M9-s`GwGGO`iG({S8s|hYOo?8`9^R_U<5UA^7*h6z;VOe3rxC|s z>x9K&$y&4Q>0_y*R_ry?AjouzIy09*kmeh#9#*lR`TU}K+w=sY^~_WrLGi~1Q$TZ# z*G|`6JLwHRF`lNiNuEW;N!vDCMDkz`Qg*#H;pA_hlu~Oo6E2A+@Ymky8WLY{OzCo@Si^Ti*I+mKe7AL3Cl)xE8-5J~IC!F7if5rdce-5$+H6zGp0r5=B4o;ZcdkVQj zSlU%}?sT|7oI7K;Z_EPh@?JbC{+k`(K6y#Xa%4P0T4Z~)9I4P!c;aHDP+yVx>9asX z`d={+{*XI;rtsV`GAmJ6S;aAf&QuC8NkL4dAm$nhXxiA3&s~!dfvmxw!6Orh83cO} zS0?8N3y|D|x8kcmY(9#V*0j5Bky7F`%>&~QjF#^t~&K5k=TL%eG%yu!@vtUXvA60aK zx{`thJYj$qrGBp|v+Pqv6p2o3x*g3$`22^fSX7u22V!bZxTT@R_I>sa&wM7CRoA+> zg9dQKy@#NCAkZX#c>4Wo4cDjH5AM1?dGgJb$S+-4Yj)7S`rc9ifMG~(>1x1hx1Aino&gU1LKS>0n4vd;`x-1=^e7+i1lW|^GWzJhe zi9_F7e5r5ZJD>gF|Ng@ZzxVZ>ugvCNXir%@YOA|l^LZDJyMM_gG)G&;6S%!;<4gsu znYpAa5I&Ih%gh!f%@>;ANfy?H7hXI<+W+VvDrTk$SI2u7YAA z#`K?PO*6YUvccY8-%+x8sQK}ZV*WoQt3F2#Hac()qYww<FP|x`w4EqY`Q_ z-2`H)d%W(2aqZ#Z*REM{n73fdLqpJOMVpyjx*;vIF}g{2-qNYYn-kU7do>`41TMb~ zla&??;LmIw%{8r{BQ{oW1%hP^rp@W3dvDf>qD+)1r3`DSH67X0JI{W0oJvUhuzoB{ z!&UiWYtiK+0riX%ZWpQz!bWK_d&5lT6CTJ&iTlylqi~!iG)+GmbQd&YNw>nQ2l3<0or}xkkHM6b~jW zcveQ|`a6u}%4=t6dylBRH15!Z#RFlY0#%s?D^PlVyxu7nk=g09M{$nR5Dv{MNMKg!j7!OY+tgPVPYqItnmCE zOjp;~V*^Q#4yMt#*|WnPD1YK`;nWe@$1b|oMqj{Vp{!Ka<7G7c8fSwI`7@}D995j_<79NIPGYJMOd zFX(`qI#XjKSXVB;yL7bMA?kyIV2oJ%Vn5E<-jdbcrk5v8PGf?=ZM)A>hJfFH0>VeQ zUc=!a0idVDDP;G0XAe*Nn^uXkMituJpM*lh*ansF#X5n7R%@<%%|KWx=Y8@kkS zQkOuv&nEwymK~sG-ag7gI5reZ0C}h_#a}(zUiAFC%U}4L|FZMNZatI=Em8BA=bz&V z*`#9Eaf{(wrmHqX_7?W#UO7^JtutG+Jb%&-_Z^G-w-R*BH*TBbgiym-MG+W%w6$3? zoP}xxhrsBt;HE0c5J2>9Omr7BR`xzX9<9yCx-)T~2tZD~wmAFEciq$q_W8L+>G*gTT*%5QugT0-op zK9mAtt8Y)?!#!Clt6djcxbpIFz%Y3NU1SRWQf^&(&i4-y*!YycsLyR z!^4enblE3+xA2G%H2Bz<24Zb}s&hL>xR17`e5yB@(G$)9uL+2O>)fKQimUAbo7;Xe z(G1tM7wqBQ?X+(!wOvb62~8rNhH4ERD9tt&J9N-8C-T;hWDrRaK5UyW-8^GkRPm>|G3)(^PF$n*|};m=&H z+B;x>@?==qcrhLN6N8zw5^7!Wsf^$~s;?_xSC6;7ccJy2h4h75&xmfMO{>1t z-*|nDnj4I{(QsjmUaW|N93IQop*+io*&JakhgNQ)HkR5CR0T#ioT^H}iQ}EknubX^H?Z%r6N3TwE**hGh*{Cp{((7fKzcC0>Yv@Ved>NAF_QU;2XfFy0H&z?=A?AtL|D)h0u z+uTCJE<-)ND?6c2@Zv(@k!5X!?yik)^2X9OO9byVpcP@5>v3-LJQ2`iy z;|8eD4Q;)h{PW@UCz2B~7?jh{#eid^3TU92wMn6D>2TT15jc#=yAu+e-Z2K+jhlKz za>M0H%K}jSMYE`)83+uN@&Y0vz)F3#Yez_!+hZZ)Q=A6|V|MH`MxdrQks2I^3-%7Q zWvTX`?n!y7JH&$BXW}fdJlv8;p_xB*7PooB@GjyksEd)Y z`yFmzZ}`Vr$O^3JVw;v`xGXo3qlTqGS7p)CAW?a!_y@y}B|v-P-vr%AvWR0ifAE7F zuYLc!I55Cc!&b8ifRaCF;}!)TGW>YO^tbQc_`R>Voz|hTlevu1OW&w zj82LX|BYr`W*B-6FAn?27}!3IN*%5;Rb`jY0&QRg5F1+Q6rAVVqxzZ+Bej|Wzbp$# z!N#mEKcxtN5-Mr-)UgPrB^j!-dF21)>b|2aJ*X?u|Nq{2Ko$ZNTAiehm2=KHcFs9g zS9j%{Q&;F5)vZ<*iU^T}gn1UWv2kF)HW-X~9$-9Uk8PN-jhPwS7#sTi&Mo}bytmd} zy-KC3Ti^Y{348CePd=$$)y1=hyl@a?{FRqap`X;WoGp9befBdy_-@6GlOH^h@}bUT z*4AJyfPc)A_vNfMw`-clK18x50cR+8#c(ox7x9uoErQb6WniqVpV34Ousw0h*-BPr z#%6lOIblnlBm{|YsH-qgS`uxyHaq)zNrf*Os4y*xUQPts2S796i!Ngic5bQI;?z z3pZEvWsBrubuwY9d?eb0@^h#j$7K6eNFpa~76>gUSS)A`5D<&e-k2NB9%~wT@5=Y? z|MKHiOwG{>02KtALy_*bYo7l=-7u@wT9TVkh$gUXUNI zL3|-7_AQ}9oe-pXIkB1=!x}y&)leA|#i1t7EnFICiH*&AX|D=rcb89}QXtWPCWvo# z9Ic)&$D`W!FCCqTEi8lLO~TqYC-ZXqL6O@Hw>&i#&WD|hi1RmeS8J(!91xJcIM5!9 zK*CW0Q6A6`oe#rjSUvEhGs~~Dm6Q7B914*zo~)%kghPe% z`%9Mg6wUAUMb%R$YMwq_aqCpg?X%@q+kiYdmkw>1-J#l7^UDh!$uPG`n9{&f+~=N- zRYTcu53zmmo9{5X)WTCqsZPTQ#4uf7Mc(}3>Kk2!izkB$k;M?uojKUUnv180KL6bG zm)?4~D_y|J{N3Ddzt#K27t9whma(@2YJrB%Upk=77DfOgfQXct9a&3< zaxWc4AB6iHte~$%3>0cM_BLdV>?uBfKr@AyKve{Xt_o$lxA>wU;z#`GWH=;5hFULW!=93Ww_K0bt^%AQp z*SZs5Alcz3&^C?=$Zi;2>>!wGLDOs+*(T755{5o-A|@9&Jh*Mt`RemkgY^6?#0!nO z#4OurQ6m1k&GOW=Y6HeQzE9dJjO*jvnKB~{m{~vUtvo1tN3_YcY-&Qwfc(GORUGbq6D(w^B3)uI|7R@PgUx5E>1z>PY0FD zq}n~8--eL_vydM>m*km}0%%zoGp^}MhYVvalQe)`nL-3&F_eA->F$cW`Mt)O!DU)7 zW9j9KXJ9N=_n!FJory2Kh9jV@)!~XxW`46ndl6o6z~pSBqxure`Uu<~vS=7dL34fq0x;YHBsu*HADKf*{)OeD3v zI`*BP{r7*m|MOda{Cde$ON{fFNVOSfy2cU{n|}#4Q@U&H(=o|w`Ma$Ur9$y|tEM1Y z0RErDjWz@=$A6VGEzmkzcPulXL&|RK3P$#PAkMaWDLIotP0RI!C zYBms6s>fnTK^8L;ZNvNAep^~97LQ?mjeu3mAMu6q$#ih_($VUL!(55%Uh$qPEBF|r zR4*(NO^A=5&|=wl5T<$Ie%5KdcnWwE!ycjA*ermhqcGJUnvV$r2_0A$Ez&>%PmdU_ zI-45~&;8XpJE7irQv>)J03ClV2r6r`Cwn+q6@q}^|0`mjV+Koky@@Q0Xz+i5`HA?S z&rEpF)3YdyRo&Ge?%)!Z{m~Qr)^bd;vt8wm!a@P+LOyrx8}GXiFacI&Lv z14kI)+M<|Tc9Tx92Jm5wz(@OH(VjMZU2pxv=SoGbkJwW$mJZ~aB=x*|ij{4i0_lL^ ze;`PSKEhiqzerZF0ElC7#72)mM+w-+E?_T}Dz)LNj>d(rewN3M?GG>fr>~rN`>EWE zC*V27SK3d0=K9C~<~!HE{>84(T|e>0^trcgUisSl*S_)jiC=&9+VB19r~m5v@Bhk2N3o+wexy6gc3qyIRvVbq zgX(9D?YCP{?;pkyqh*y>&Xiv{p$hesCFEG4V&X!!d2~Dex9I#4orUCx{{^#Hd-~bG z`_J2+pNR>h(Hiw6fQ1oF0zD{-7&}^n%}kx!zHxGE+R{Eo@q|yyFg`IAFBd}uCZ3db zk9MZH+-zasEp8__Qf%+-ZGu^WgW&lvr8Va&m|F^@*S`5)_uIGYFLml+^(lhC`*Zn) z!UnA*ZdZ6h6$A#zAjGkVF?^($kH}_i*?^-hV(Ad@#dwY+E4r?qHp!K%;*I!k&7v9D z@!bNcIvhQUO7`_*eW^M!FSIWk3MoMR$CZb|e@GYyoW`i5)aEz^t6*u(BU^ov@Y}@E z=nkMI`cqf-$qD1Y>EUHDl)s`sE$pmEiz2?!ed+rYx+D2szSfv1@?}GHi^v}n+2dxk zYfSL@IMvtNO)+!3HKeR*;vyc+*GQ10^o<+(3ODxUa|0mJd}1`_9a3g03HLp9gwo^n0y($a3tT+f;v{%x36_K=VRMsl3?!71hoMH!T7Di)<7o=a zZ6FN_r|^3cGd=*3%K)L1qX+LF{9Faao{VGOV${`HcDdAo`H>bi=B<6hVS zPR>$*FUXMSNEt_@bT+IzTL#Y&sG}pcTAC1aq{^OU>lnm;&1|AwDqq>dF_Qd@!+&C=T*PcIABY9VD){}wB~z!9ih_MTJ<03|fRO3p%bCLM*g zO^y7@8;!S*sSG2qcbnwOp8pSDsJOCM_K{7LzK&en3vDOuXm?b?5vDqG9`7l(jm3@| z1R2qw(G{iCFRIY~VpX)Dmv|TromqBin|9n?krCv5^d+2De(4HpO%7Kk4wR`MJhABm zC#^4h!bTM%U4y^!{JFPoU-`!84!pTkc4M&q*4VjsUVi(>-)p`;Rxr_)Jh%n$m_K%? zbaFg%^so&_s4=pCy-)d-j)tdaimsf?TR82xfDF{%>S_PXi$~vj=J3a#-}b_kh9zc@ z!{bhNRAL8QgyeD%Ry$R82 zA41vHv|SgNQ|}q9yVb{EAYgB$`%35BpT>Rc;ENxbT}H3 zMD`Tv*)|@YBmX^$#eTR88)11U5mBvw`;iC znOD!(T|d`!v)?+}Fh(1+1D<8)(KlKmYX3 zyOZ0Vn=QU{%Kj8FTs63^H;-BmfS@aMOFIlzapvr9&{_2FGso0&?mfD)DESf-1WNk2 z*2AnsGh>&!QoOeiKS-tp9@n-cjcqdoVdx;_&@(Z2ym~Y%qV#y4J(9|G3V*10AbaEC z=A?d5?bGY}2(pqwTICD|bZ!k$c$5Mb8}o-U#Pc;{8R9?vi~~rWrTHoGh4}9-m06q+ zc$7HL{z8UYJ(9U0=e@jQaVUz^TeEwz-X+VGln1Tm??= zp=K*vI)s-IqE`=Q@Lo1}%iFVH=7@~xw^Z6nda4HMN{=dx7iQvZBS4Kc`z-#iI4MZF z>ts~}ZWwUH0YMaPr^p`+4%*8-%>KSwZLn3 zd(rt__V*Q?x0|>bhymF!5e6d?|Gky4&v48;6RsngC9>uCANY@?)>ppwPWxAX{Jnp= z|Ff6>;+?YDScVb^2BU9Kvkl$tMZg~_{dMi-%liNNOKl9?fcfhG<@hfJr1!DbNjU$g z|Ig+y$%zgqc8(J?Cg72-WdI~}^29uPCGnpZDA zOa{3pt$E${Oc&fw!3@~+yeJ+h8I&~cL!nGlz_Auz=9`*sFF)z<6g*OuhCMDpUr{^) zgAh?8rG*ciNR|i~FMA;=0&0U!4Aea_L@~Q}|4WySy?(_AjK)Dq`en+iex=}c$%_c{ z@pjA9YA6*U-XH2sf2b=n7HlO@k*&{iCs= z>joMGa91$mKc2V0^x&JbrfW^;!(_rGsi)9MkO+MC^?eQ9pM9?K=GhGDjws>k96UzY zNCI(h`PII?FJIYqZyt}S_!qUHvMtvJEz#4+hohrxIFOsqP9yvC;D_Q;kC2F) zCjBwEL8!x5LR}QDj7rxjqkq=Wc-?XA#trc0rZAmuIY*X+jr%#mb+f+CX!>vxtv$8YQ z(mI7D12>xpWRNw3+12z>Lphv0n#5zv#$1$U!HGuj86s^I5u!fk>sG3oY7gz%&4Y{RARO*wU^YBFe7S8Rk z_KPQT&E*q?=eOm|)aT6x87fLF$A2jxVE@6eIPfpArH9%v=uN1Ad@cU(yVvo}fBvuH z|4V=VS@EANjb{{VMAZfHkN7Xt8`O&VuaPYcS57Iv8T&JHSdRY*7PvmGw>*WG{%l49 z{3+m&u+01h-riMYco|C`eO6Dg|MYbt{rM$FDf z3m;8PV0Ec+TvNZxi7sQX*%Fz+|3{nX6O;$!RWcp(hqS?#+{x`Mpp9GFv$nE7&4@kI zEkA}D!03tp$|tQEwVrF2(BUxu&sDvHp11>%SU+-n^J6DAI0J^-LekG&p$lMAB-*G> zU3!JRj}u}T8@k)m5V)EhG{^GNN!Ke>qkIPX^QGFPk}$<|N8eo^Y{Pp@GH}r7w`p3oWd)64G*H8Wfl*$q$B7pul@3ciGVN# z?apzW7HCd=>80*pxl{90yU!>Gx&73)W_)0|20X=Qah}XRZcBn9lafYwdb5_L@4&jC zjQdNq^PxH(!hyPrLbUeK(O7GO3;3nen~6eWt>K9cK8Ov!RMz=ZM;+AzXOe%pBj*Dr zvk|qq<3}Gpofn%>PN#h6WYR}0oIRKF?~ZJIuyfEUS26{)oc-=g80vK zIIXWGZJ-jK{J@b^HvrZ(^Spow(rJQYn@AP&oe-ByV39jW(}g&wOI%`8v9nvvLwS@! z1JFrD5W1#{iwNanzb;M+JIVmaztuKg6u;?)j%RGnY621#Up!QIwVOdDk4@qk20lzd zg?GaHz_A(I+9KK?iURY|3Sco1cjE_qQ(pER!QT&SBG`DUx|NgqlbA4;8*H+x9$pmDPbA@F>C*lqkQTPzk1ib(iEFg$lPENdv;B|t74f3WR^ zS5Nk6UDjkpW=sJX6^VVOfyLoT2gB`OaE4a-P-JYLHJ{WJaN1a9)_85+wD8`XH`NU4 z&m3>CJ5tOK9n117948tnVT2kxP?X1%y2w!X6$Mca1?fc0H)%0INxy)AhO5BQNdQll zQ~jmdfnXAQBmN(GzUMnX|KUIW{Aci=s`(wDvnP$3T6fZwZGhyDMO)GI zZu)=UF#_MG70#Phb8=kh}GD)rI6zQ)x;egts;`r26yVGq1( zI9Af=3u4(&cd;FjdM@&z%z-95-@*Rioq*y=bPO-EdLFF92(z}xpWVSjBkl+LwtBOj z_FxKTkCiU$FJ9P#1(1Z0JcOox9d&`H5eOz3GM41jJaODL3-2Wo!7A7Nx< zDQ~X2aITgrUMWKA;0aZMYeKyy`JKx+h@+ay}18{Nus!l8|^-0(ny(f zqtb)+izG+^e+Xt`94!16_~-WqB_#ewN1%z;1#qJHw;m_BBqJUZtY%`_4n%o0Dg@N&&}SfAQ!i?yc>wl>sA?C?^to61ktz|3e!B2e8w8xSm@A z;y_Z+TsUJN;#tZyqBFnv!r{^1dpT?Npe7yR2!99*waEq<1nyLKb9l!K3nhykWPyNs zVFddl3A*4yQEpf)29rpOac<0b--q{EdSPkCA9Qdf8!63j*3&KJ8( zScj<0euS}_#yiJV{*R9o#4y4rrLlSdp%aCW3EZu>Mi0Djv;OJ`d%ZQCRSkE~#$+Pf z|CtlNM8_=o zaJc~G`z99{M--jkQha{fGPc8l4+cF@5lb)y}Ao~^dJ%c z30*p~o;aDC)FH4h^S?1gWl0(RKm8|dKL-gZAVC5DBK|+wo^C89sk0a<4BKb;Pw*M5 zUgi!P__E&7fBNP!?aQS8-aZKo=wUKYl!&%c%4OZwX|E8w1z1j+_TO!?8IYD?0zK;Cv+% zBfY%MEp$s1{F%@LESPoxK9DwDnmb=zvQ$@czBY5pJZv?0L=Ta6&!5IG7|}w1^Kf|J zEDMF=ea}z)?oa;i>p%aOuiXEKhMOn!xdGRB{LQVLOI>j)>xu5P<@j$mB3)28MVt*8 zE z{i@!B=Ys#>p#-!Z9aC62&K~N^j9}7P*!Jq>J@=-wCl0UauC?PB%d?^_d&TM8htDKEdZxfk7Kx7eEHg*I zgsR(SSC4y&iOJ#826Ko^fUaIy=c$*iAt>HB4FTA~Bp(MMrr~*^UJqKx#iOIUc;WZo zpjTNB#~!bt5?84Tt!mn`Yn^*uyT13edyECLC-!pVK~qWrfC~x@K#B|qZ$$TK08L`@ z^_Bj}CLid^+ID;F?Z5t7&6Q(zpFwyMwRcV0RE_B>9fa$GRTn5U^|FbXFY#ZQ@ezCH zts=F1mwt7$aot3r_-|%BX{0c1qM%@|I`@376-$M7!A$Z0ujjMM1eH>8!( zeePm~`REX5>X-&X?v6nQIff}^S0VYmZpg=%vqHy6aeBE;P!f1)4BTl7V{HZEtoqVv z_7P?0JAf@8?n|T3XG|1&_z_S>9u3c9Ts;8@5H|7OFpHK=YuTRx%vr7|oDd^y?kkB{ zURXJtFE419RQ{QBEo+CfNJE8pr*YMA(W;RGhE!T(EPxzgn~axnazzWGnJ!BK04|ey z0*2}@*N!ncY`8Q)-?(8k-$_Pi;7MbSIN`9Tq;X)&q9X{82{QjnLXTc%F!{;Jd`V4I zB$u)&z~_P(Bi9Ii9v;kmd^B^#K&HqKX=LIQM3Nmt{dLOk5LXP5a#e?S(|AhiL>agy zbEYa~rie(%`^Zqb47KRSzEW)h(}}9ZbJh}NPa6TKY<=bgzGl;CzDhM`vOd>0L!46s z0>W?!Sw0Sghse`I$AZbc37wL#A8E^7YQQkD^N7!L*`KKV zTT7>Qmd_l5)!V{QGap%?V01SqNvu{aOG9*(CJUqkKvU_=9*jV#ZSRx2$wck;HBwQ& zco>|rq9ciuCs0MfmOrz-aAsS{%noU#V&Z7d=x&3(E6*gab^!DehGZEgb0qNo6ukQS z-cs}I(A2Pl>tY98DBS>*Oiv`#wq_+7llxj6lJ{qR^(a$c78czltc^A)<2!?06`wzF zD(k}?g%7kFtu5pr9W9ddVPOgvAbiSDF|-y7?156qF+bPax_j+fQlVwdR$B^_GTkI+ zc@Z0kX(5q1o6nr#k+Wgyxa-dF*Z%46|Kt7pfAFtAz4xbI7J)UP?mf^qwW_^rnvv)@ zl3 zqNqSWuXKO(Oj+*eLB9H{I;%f?I#67$YasWahfozk5(x#S<3k{a7Zd!8W_DFwJl1%% zv;OLt!1RJ`ssC_W@h_d(5bDa)sjItdM}Fs(F!X@%+ZzYB`$%j zYO7D?a0rZ*i>LBeo}zlnW=!;9(^v*5`l>2#p4PKKr96p>I^A(5&D&f<_W5eOr0$^R z`e4=N0n#8qhrCAoNw%sjs=ace|4T2V&g@o5Z1fuIW7)|wC1N} z-@nj!Y0H*d2kNhF-*WqK$$WFs1qzv15My{bXKwcs-8GtD3bbIHyK^&bq#bSvr}Xek zuQ&W9y`uizV`w9D@qkU&9l2StbiCz8zd=H~rzJIkH&C7F0!Y5W6SX?f20%x6nNSv0 zQuX^L7Qm@n+d&MIM`;5>2UAcZODm$f>`8&c7ieP-tDoG;OQ%t3ksU@0%9nN>dS+NX zhNg!DFHy$>#E`f2nOP zcya*FiLTuEK)hymupvbh!kKjkOo6xq8Ehd3!UDr9_-c9yxyy7U3Ltf;^3aPtzwwhl z{fD33fA?>`>=v>xODr`4hR%ln2`+sILiPFT%6>^nHE~a3@F(ae^>{b2l*oSrW{vXOC1* zAFZ4+z`F-~Le*I?zPEC|&BO$LT(RwZ0`|-1j#n)nt6Dr_)Yq^0F+;n-n0Hobd_aPB z;*etE(JTUDl%%tbB##^IVFJH?tDk6 zdI|QYUk_5Fi3pOnBVX6>#ee?GZ{NTFo%=ug@=yL-&D9fP5&4beVodn))2WZ0NPWD` z!n+&<1lAZHB@IEp*+gKkF8;wM#s6RXhaY_GKmXyd*_*r{1{2OLKEy>qBjuBp^|a$1=GN;tcldE(J1czLZG<250conH3((BmOT!v1(Grw>LdKQhjZp@u`vA znS(3NmHE4NR@!1FyG{J=OU?I2xJ-zp9s#gFx1yp8r$6>L-gR1W}@e+L-!ICZBgbzoxi2Ng{z%f;02Vgv0-7T$gD28j!CGjg>4~#oUW|7x~=urf$dKn-E#Y2(~UjV z*R~fe))y^s4QgUjvw6y{^Xja{eT{dAxe39h)^=Oh%u=t>qy#w~#ov@4-_;^&Nika^}bm@T?())uWqH9%a`K5l%=GUPwuX%&2NTX>48? zH4;d802ivxPr&=YiePYtiV(iK39=0#S|LiYBXk4qd=SK_mzGMVhS{3=+Vj$Q^WD>U zUIanme1QKU`0h|@cd3_QlWpBnO|RstIBeDAHb_D0b!{|RG69t1;3%)S_{Fa?U!uj zp8$*nfr|gEEgY>mEQ2$Gf5yPh)c#f!aNhWKw$gsmF+=;!!KIJy${g8=q}bF^05y^n zC}T|!7$puBQ%50gS0MF;$iJp7pG%M5)eZ4$k_Cbt;Gm*qj^#f20DO-Ih(K(V0z_kn z9c~G2mIKlU+JRUGFwtxZ0?l+W7NL{aBH1WZcjbuef9R!&z0VDd{@U|bzW({P zPhA&JOc)6r!hVqg8XHL9v)1)U+#M!qlZoNAaW0F%X zYHYHTO}4{KXwpkvL~VNv_^233n7R#Iq<@fsTYD0d1ZW0~!T?3G@%))>BDS^WB^NrZ zYfqYJi4imGe+R-M8{h+f4#zgSmyrr55QMc1+Jw2B8RwC@%$aSam-fS6Bp}&egQF@o z?z$ZRNjSnZY}~L?gZMAt1L|QBj}52$n8pgy=e9`}HnwEVRA$dsWzW>+owxF-!t&XT z!}-F9cNV>qXSbB!=pX!zPw#s9l7pn7vf*7p0(;NkJUl_G++-D_Fd~3cygYuklypkR zsw*)CY@z|hoOQl6ltQDaFnOqpBMIzixE_`TTN6};TmcZ&?^c%%9_lc5mt-f-s?*ur zY~ZW935p$uXoVfPhHBH+_7Oi!E+H8S)4sy zmCxvYsAYXedeXVPOJ5YsCMlAoMNe_|{>I)%ZU zjZ@_(U!U4MY>8Vw%ODFfvKO}rwz(q*Di%6CYe@qj_x7yWW{rcl)#5!F#6*Urkf>gq zW*F2DR_=az$aA6h7yn~>JDKQsO$Zx?3K;VEPq7*r={O|<;vXDA_=uA9kHj{44UzJX zUY+e{f2vKDt$?HcXY6L%i{)P#11;vQDi;ouUmDa! z0srsupZUW^`?%Xu`9E`hP*JOdp^hOulWPW~+E_vE6;lA}Oe=K;8$~UZfRO9M(u)Q| z(N`0z0dOL`BYG+*d}=SAtXMh>?WfLC&{khOSv0#>pw>a)P~2wFAtxtJ^;oWFhXW+v zLI-KLyE6vKQ;)35yO@4tHgM+aUW2igerK@b}xOgIZM8d6Y+`J_Ht zLe=jhm|U4!mgz2RywTS2>6-?ijODT^ z1TBeWzT%GtT%i(XBZFn2Eg|$be*O<%{MR48`;UL|>JR_po$vn9iFdAGOUd$K=Ki9; z13w7-MHzG3;8!e;iJEvUp!MCu9>$0sBNaAIX3p+!xYK{5_Hp$rB}9Q5CEztGrr;F9o&{}( zA*%PVQ=uS<@O_f0AHam7M~PW)eqRan4@ONe77D_}uK!2LdN zzSe8QaQ3<}I-CTe1??YVCbP?~7CeGo12Sotl1(J+qr0=Y1UPwj$%a~cfB znfK)BQh>TEAet8upcRiZD9k-ixeCl7LtPug2)P)LdK49wm;Xu^_gCXp9euqGc>xK0vvg`Wkx^_owLIe|10NrjQwAi-ue6Adj9*L-g@`4A-xPqPzz#Zfpa!=dI?wY5lmW~Y?fS&0)Gi)p1rJa%fF`su-6ibTDc~Tg=a0!; zC|ye07>>68Yoy+Bs(1l7ZVXJEN5iVnb%UAdlLgsR#hFv3DWe6dppfcOKA?{Y>Jkpj z=m5?+8dznXZdw-e5XBHdXKZ})DaeEjWT{cL%pHT{lsQYjBRtYN3YD=qxTnBqKmZ`U z(8AjC#bY$y8~SR|qlTwGdZyr)?T8WZd4xvVg78yc(~8I5F#suJjmpc1@)x#igcbj> z3xJoG_w3A+Q?&Uo)kpy*{h4Hnp+DZPtBb2yPOmYHhYJli1P$6XG!+B!E0$U8$H_C4jHRr-M;aZFpH#SccZ5S_vHCed@CCHsWaNzZe z8;7_4^0`e+Ig~MSYmBk<7V>;Znb>jg^~(pI8MmMM=o_;_rG607PX8&LB^2)%pW>`J zg=>A@d>x)Q_k2yxLUqz~DeoE~E7(IT71UruMS*@83JwM{#;MfRs&2@YET-fLieWr} zi^m4i9_i2gaBupG{wxD)g%|dbf2bHST+DewY!izrVkp?KL;1B+G(4$OI}W~bXYXrQ z(kAz6%3wQ8Dc6sMiSee90x=UQ%)tXb&$P4lO02fz7hQk1jafk=`;?^430Mznab zM+=*uK54$m>2)UEGXk{-!D)B?p<9*LPayG?vQQ>yt%gE- z`vk}7@QW)o{FSB=8-Bgi0Vo0jWh~b(-p1@jpg@P2;M@`=drp9jd4}zkTSv`8WUS3pc;{>XysL-BH4q zDFy~;Po62TCLo`CQU~!*P43t>t9SwRCDZ1%b`*}c{{Q0ts`iNgihnhBXw+jjN{)2H zoY~&?yvbd8;77#GNR2zz#|$^lZd++;Iea1lj1F0cv3khNQ7i0}JT-S>5Aa9Xk4m5v zQq{-s@A(s@(?^OY4_O&gbbc>=l-oeOg;Cco9Bx=>1NA`u-ETgH)Z^Y;-&OA5m)%5_ z{ccFAV6rP40O28${xW*+a+CJOKD*wmP5oKv!~Bsz^wix3$-`?aeY(~klB$H$2d(02 zi!b7Wc5}Eb_O`IBaDi*jG1Sl7fx+g3XELo*7yko3?JJ?-LB8V}4Eun;^b4!ZmZEj~ zN{+p?@cIwF_L(1j`_dnN+JlMQjPV3q40D^FFrb#FqI&PvLltYIgx0`7dW*uzhl;hI z6k!JrNE%uu4rCCtbwaQj{DqWZ8Fz&ASWF+D06r0m05zecVCqUMA-Tv|5{mzn2vpZD z69~wy3&BwG2}-~UEr0_CBZ%P)-=c$_47wJtYW@@srVM+uCtI(Sc!Hd_aTKYQbE|D@sO>Adp|MHd@#X6y3jm=oHW7{y`M{4T4nxTMn0{QJ{u{*Pnpl$2rM zd~yRj5iHM!_Oi`q%URK`I%O7q%a&&cc04r1(?e=b-+tzR~vazyFiHugrhsY*s)z;L6Ty zvRGw|No0LN%e|3HU;b3*TbK8~Fv4%2ARkCBu%LQT2@;BeU*$}Y1C7s_t3eJD`S=q7 zp#;}ZDpo7-{Hq^~6kvk@$O!N<;UtGm4a_8Yx`Jt>tYHY344$9cqa#VCr9h6VbaW3P zoIs?Uwh=6*(T$l573D%C=C;WQCgutkPUS5gVY>(8N}Vp3=8~s!Gv-QCCW{5hta%WD z1p#Mlb*a75DY|+bL^JC5kM?9d+_!1XSi0<^B2tJ_%YdYGPZgKW@=-BL0AXmkHOzxc z$TE<^1y|%Z#^S}-2=?nScXA9n7fc^Obb_Fv(>Mq*!33`T6!vKf0^#I5R=)qGzOseg z=r$1>wC)T@sWvc1P(^nR6t1&tfV&-E5a88%LS;0J{Wvom!Z9m{#tsB}>3+S-eYBqws?ZtsakR3Wlc6r_l;e2?m~W z@njwu>XT!co2K(NOoeli6aXSny}N2u**TW{jyL;x&1u|VJy}MybO$80%QprK4$PEH zK`fNE{2HqcGq9E4J(=drA`EltT~m7ge{!j&Y~yTj;)Dp zh136^`2P$2=TJTTKky&?Z%4MRj)Acx(1yT0x(i@OVlSXxac&&|-j;xes3s<7yGjK^ zFh0hgc^w|dV1DY zaGs*c{ROi-1Y{1hp0e;`@A8pL5@MNvt;+qfF{5cJ*Ukt51-Bu|B=PqeF@z^ zaz>G#OI7>W=~RS>nKcKXVy9SesE>4KKzl~N^zys^@ZG2X^fykub;%Da?4x@!m(&p| zBP{c>94=aka9qJS#2!GiD&oJwUR6v6#w}3Ipj=NVQt~{`@iQ^GR;X@|;vY_B^usHG z?Eno3L<4x~v2H9U1{^x`fB7s0BUg%IF}dm4t_Vko5B`LMin2@1|Yw zDUrVtRPSUtG(J+>0=}R|Il+A~a%Ifk^2UKx+T&2-87Fh{{?Qtn&K?fcih5OX8^<|q zK?x9EC0`|yKp`F<;+aFD8DsMP5Lt^V&TF}$kjH61DsLP^WC%wPjBHj3W3faYjzMuG z{wGZpY@WuZ%N3XolZnf^CU8#{cK$_E4u?D3-N22#*jw+7XeqjYn zf2BB+HoW7pGdVHX-cb;U#IRlSrIJ1!LP)=;K)cgc3~jaq$BmIbvQufw61o0T@6P9D zgazZqd>eQlxkjRE`h4q=H^xbJr2}LHM1>{_iEoo5MkWM26I!!Ix=pjgD~aSMcrP=N z$QJpnWigv9{%_L3O_Zqr*Rc#5N_l)d+qp^^Ei1dc%hgG=qIuyOH*TeS3=uN`RQYe7 zsm{B&Q{xFI$46NC0g6#?LtRQQ?yk9U9N(dgRGc^!x(0Ty?kH6yf=}WDgwRDcDMjWI5hv?O-}k+P2@A?Ha2?sf)>GiiKZuUgE#{-w6!W(?|)}8AK1Lq25%& z30a}}4?~+W$0G$8AWa?RY*wk5M;sK*Z8iUk*s?y@S_kt5UQKt-6)#D+TNIWwqJlpK z5mLbH*z(MmPRdIQ5MDF`Y%nVuE*-q}jaR?-;~)I$-+%4&tHa5-%kaJAoSFSZTYlbn zvo*w~qHIyg9p5VcGyhz!|BEKJERO)>jWmk?>)Y+UN@1!@HmOz*V5irH_hRzS>XUfRI$PQz*)r%)8=T4Q) z9xk6g0>iQ71&l+_6Uxc6875?7u})7N{l6=M?e#~A^XZE;6rgWYQPM6n$t8ojxZ%xh zNdZy@m6Qi?8S4;N&+dTJ_uU*O!^}yQ&mLDMZur%fo;4t^ojp`L5&qau22B(I!_Q@o4t<+nKil}*mdl+ zh0?hbPzB(U*2#vTbzNaPs`yvr2R_*kCofUSlWWFkD&;@@4{B+M#?MCM`fzy-k(eo} z*jXQye3%6Vz3bT&ZD_#sECCnWLCMj#r$Ei`#V=Iwhil;%tPgnPT*c)-eRumyqcC%K zFPzz8m%Jr|OHmUB)r%;kG-Dkz9c7X=C?%Ipaz99HKO~7Mv6c({@o2ZVvaGzybL34# zwq!2Eb8!P#&TlJYH84}3HP?ViVX9NSc(CVe#M#6$JZ$4C?X1F$I9{9xc#5WY2E_ZnNsmJ>N+00X@@w0A1CJf*6SuditPWzRn zT=94CqW#a`wE0($ysE84wJZ*^n_k_=-JL@?aei!yCr?HCJ3QRCj3YI>Q8CeiKLOR6 ziHucahBu{4endHliB)51YJM>mu9Y-yf*?nxptCh=Ovb4>HANeRI-k0*yvX&5_Pp9( zcIlw=th^T?MTX3=W)H7zXzDSSEI^V@i@jn4pu~i0z?%o@z*vbZyOymlOEiGDP+bc0 zD~D46m^4Cab;ZA@n~ejZCoOawsUqJ$xv+mimr*5i-;+2?-p^ZVbt{}(-F+3<-1=`LU=3MARYcvZ&L*>BUe{URAx${Ewc?J` zd#l37vNI>iczaJ>_Rx-ksU3vdG zFiYsMp-&SnNmEe?D-OjIC1uPaC2T@@4e3^x zvxuF-!#&wFqCD~HpB`#^?-@D=u&o=3+C)stUuZV=2%Sdwf`!+sY^Sza&Mt(0=xBES z;vsvr{4R;(TxqZG~6_n2Ks-wr>55nzq7Q70+)eU)+{AOA-?@5)=2rO9-L+ zb4$+e{KOBx)$yr&EC>#~xv=G#Y4+Di13S&E$)wh%5SgeCrSbrZxh^E;<1{8p%FSAm z*=?cKoHS<_w!`qQ;2Opnr3OVcd1P!w883H=5*2u;6h7RQX46^Gl|yxxI?b%@dTBi8 z%6@c)cNRrM^=&Y%i=}pwmc$K)`_7u#Z?A#C2$zs$j4v_CFI+rm$v8xXr!;gi>gPdf zsDKC<){)}GwyE)E`iCHkk+#4?%T{9LWdw6?B@8A+HL*uPz)^VTFYV@UmOXm_Nevv3 zJA_0BAIh|me6i6w3`Jv12_;6nEg;6=C`~=-EGWw^9|w}J98JO6AWT!|>eq1Q8E?RN zMhno-m8IGWbrmcEJ$%&_05fa?`!3Mlo3^>zI4waQ&Y*$N%+1*$LTb0cD zEz;Kd=|aSp8N%oJ$#SlHIZ7}{9jnlbL6XjU53Vz&V*eB(qmRVOWw z|0VKE4M?1|%_*`$_s+9L@rPZJN7K)}@S%5}R?tC!A5H$yU;fE=4!zvDz9$=oFNWI?y&V7TQo;YK|Ec%I ze=Kl$P{0xY;Xeros3Du?_DsgA_Nf2;ZgMaCqh_xDg;p1hZUc#1iAb@78}+po!QcMm8Y+JAN5TiLO59&q43a{PA;P#|@q2UGiRk%|h+Q;9S6!+tWhz^MPbi$26{o*gt>kG?8p zUe46s|r(I)9;*mCObEiQ?zHhv-eHN?)&(EH%^YdDpjZ>Ax;Za@p6l+PiSoi`~>95OKivOUP z84e5=+d0Ts*yOd%9fF3^&NJu_kq?oE%FY}ibPYNkSTyLyy{B38$j3rJS=*)?VyeNI z9UzX1BOJ_w_Y!n5(vM=8(8#{&p|C_VitCS(9+{(|gohb2=rgcjBHQqqUe$eQ?XTbB z;rvMdX4S7L^^AoYG29nPBh652Z>S%Mnt!}8XX>Q(M3(`n4oZ5=hLm_@jNL)$Wl~L? zo6T}zQX(@`@a=V@vA`>3rh#uNnoL&pGTQK1U-~0G$%qEyz^<(Kglv->D3aZ}Izib) z_H<6n1vr^x02{}1Q|Am9r-`Lr_!`sP3^(BL4%kRIvrw>)Ka@YyRCR5yTZqsdt$wqK0wNGA(1@0az!2zOke*m$;g@#T(L(Qqbd;rd5?Ut1UsL5)-UPxtZh*8lbV0)n zhD_D%03t&T=3X@gnq1$c8%!N+0h`xdI*Lj1k}^lECI#;dgTr`WHVAYlR=|`H3rqfK)^dNeKvH`JGr}5+aQ%1L{MYTV|a{5pmNJYEaRqC zE=1FiOgqmSNe_{m#9b{8^A4)IcoZUsit?iMg1RS&zrfxZqpel#aBfThXs{GLxUPXq zm<+Cwk4dqPOtiJH1#O^#&wJ#Rxn0i<>lA{44JHCp%p0Uh#YNETtvnj+YgY6Zg|M?d zXL%K4Y-6;WtRwhk4274{F3|f3kD>JQwcx+}a`3Vk946Sq$(T>a)y5A*3Mk_0fUs85 zFKbpI0~`BVGlmY7Om{Rq)n(C4XxIC)jnhWT@ObvcDe}93=n$e1L=6?dG?*|b-g4%5 zgt<+)$Asl6@WDgP|FizqK-!oE3Kc@AL?+$D`mK&^!QURM!QXr~yv3#)gaUF18ASJO z5C)W_vp)FxLe&l1U;|GOOc++LBsZPp;jp!6ZaN z%0ICv^zf1eL$JiwV6=7IMSTT?@!VtRm%JN&nzG*&r{{mPH%+#+FbKgU=0A8E*_3WI zvzOWfGMqKOhx#RPaYK5YHnvmH0~H!jbq9tZ$DG1g2#|b%86jLJ-A{a|>I7^n&oc522l8lh(Dz*9#xf$LkL1fQrHgwJ zyUu{y)sZ8+^-2~xI5T1UGnyX+!SW0*H;JKq!wykYjFtkXwD7sJO`Y#vZn|~WQN>Fe z)n8aJy>;)iJ-hC9AADix)W^^7xZB-$?NsaSGtEz(D!mB*H2anXDwOG%qlV;ftQbie zrkVqSxdCT?C^K`hR&}9qaLJw=Oy@;leL(m^Czh3im1w2x3l`*6r}RJ2W}zb8klXr#?1v_Zx40^Zwuc`d@$LlmF=p zgP*^wD`ANiur~eA=^XkW^}o%(S^y(jihmCm1fB%c3IOw85&uW*bAipqjFS4F|Ff;@ z#(v9Y_uAxJJ#)-3uhbwss+Qpop-$}1b)i#w8j^aNR-Z$u1W?0^h6NuJJd%E;c-i9M z{x`p{=bbNCz4FOzZ~RL2om-ox+t&29A{R>LxnA#s8rf3}8&`XS5Zy3L|3Xa!?3$=B z+a973dmDR84VluS0BsUop+B9II$4-9nV&XOlr~$Ap^JjKC(lGMLs1T*F|2_OP?DL_ z5`m+H4!cy#p~QcmLT9RsQ3Cl_E8#_B{CIcjV;x+EGPQ@e5Bg`J{^kGj+r#fatIWf( zs;+^(l0x!W#Qz}9dU)`Lq{p97b<-q(XcX!YcrS4&@rvvt)JLs|C^SkRxh(dKM^`cs zP(VW9S1ULqtkNnGQp!vDPI!qyHqoiS7|5gkU)fV;(r3rL$-962yZ!IIIQ+%uHK%S! zkG4X3-9+UY@nHgNQmte%PXY5!nJjk~>DjH7Iq>Er8*_vIjz`h!U&#f@Vj9OaJXFMT=_JR=c^uG74{jmpLzEDnBRA~)0*2;9jQl74HsQl?w|FMKZ8UvN-yd4hO9@~+={Z*1$0F;%4jx5FP> zoOu6}7ry$wB{fBtPj8yo0v(FcCqA*kFg9omX&QxMQWIy=X@rN^-V(+6P({Z1dW$yT zRN!dmv+PRSTR-~l;a4w|T{>*yfb3rcb9(8hy+TblMB+tL9kL3Ba_a^}m2CG3fF-OZ zX*@>DM7$U!9^2v!$XwbGsocFM{sS@8#)7c;56z=BLY;fe$pegJnt=-Z^WwSO*J(u@b{3NSM$9W?o2{C zfx$;lAg>MZn*R-IK>aNH8)U=1CXP0`T^<*}BIn#)#C}c6bHgaqiCbhM=tt)H?Gc%! z)G29#7^Y18Pnjr4o5uTKNV6D6aDh%ZY{(j{gcRp_QbzhhEP2#rFp(%T$TP5m+O}Z& z7_+sgV5eHhy4+?4a;4X3b&YbESsrhaB4KD7CM$UI%P($^bt6s6m6&TA*&b8gl->q@ zM~eMlg^iz7Fxc8-bV5=txUffKyLzm2)mRa+kT;jaqYFcnOqSTg$YHPQ+V1izySXvQ znC{8wxyDN@mzU#YF_+#YbA4m@Zh*mf`7$eQOw5DnHh5w%<;j7p4a2z*A=x1Ylm^9$ z5_?sA1Z6ooQemvH7ss-v1Gmw_3(?B^tkFgwIsQeU@T_S@$d*V$H9PPk7tu9Ur*XjB z_58r@=ZEXBw<-Gtf9s_huXp86ZH1-8*slyb7XL~FAY844`CqYD3V=}6Ebcw_!oa<+ zi~oP~lYjl$-~Q`QZhrmaMYGMeH-=qISDN~t{@=D2@m~wD9RC?FEXV&?0WjR?l`{;t zsTBXIWw^%SE7?bE>M0GpXlhr{)V`9DgZ6yclk4f`(*-`&Q9j;nS687*Ng|MLJX0zw z8DICI5-6FD8LsNfz1v@Yv*p##?|bK~$KU_ffp>qa`rcEU$9HOo46P6nn3aotTYVyuI?++$svS9Yh%^-&OZ7Yn@L zqeCyx)Lv=x0VBdwRC=8IiXp=s>0N87MDPzJKO#KAd;u;X0GaL}WMjg&JCS`7#s6~f z7waPUEB^U*#vv&|!*wc(fA@wfKFK4u*wih{8ad0@g3)rnE5w}-J<_QuIg3Xi-XgybqB%lC6B!yxg}53A1Iw#~gN7Tb2r=hK zIPiqJ3AO+`wP1Sg(8*6T#E^f`0r=Le_0zGXXmC_S~WZ_3HX^izPt8fN6p1P zc5QAsH8};5xnoO>x#vamayB)w>39=t3U5xI7H#QJv%4{t!;bGGmxb^vSuISIXyV{S zgV+vPW`)h>@!ZV07+_J-sOQ&Dl#>12r1M%;uu_St8S#rcUK;p2!C5cyUMzNjyFLbiu|c^?9220o*bFRML}%YMHgq zkDN_1z?eUCP)84WQ!RKd^moyENL4(YCYn@eM5L{^rzNxoNv`2s_2;d{Lh-~;`2$-maByy102REdG z5Di*9+q&!4>5E@}?khk2-cNsi|HnVO|IBwjn>SMl{}1(McY63g^i>i3EaN{UH{yBO z+yVH1p%w6BEs6NwkTqDHi5U_9&!((Cn=S>c@6Ov0^8ONH`%pvm)SB2@c`gO)e1ep|5GkcA`ZBOCcPIZD}TU^DnK-7UY76;e`Eb(Q{w*c$JVfB~@AL*~B{E2h) z1`K~n*PhEF#eq1XA&^skmtO=x9?nBe=R|4ZBrJVFfY=?DQW4c;g%e{ewur({ArbA> zc)dhM6{h(2Z$L)Nd!;2^$8__YY1^JCQ;N{^`>O_;G zxk$h}{+Fh}%YTZ`fE|$}5&skHLnxO*z~g@jlCWg~4WcWD#`Hm3mQq%|B#?R@!8o## zxIGFFPiO*N|h&!Y%)>ox1rbHsHJ6WX zyVs+0;Z&)-XZ7iYL2zco{}9qp0f}-fA|qA=(zyZ(RwX2Y!xD%`@Ey|@18H^`gj0*yM(kbso~%erL$RgNnU4(BFUZR>jrv@$o*W&Gr1+l@97a@6ct?xp z$OwhKknTDf##bm7bI`qT*7hjOGH%N~2@BOG#E?Z|iKl=4yd7=gKPNgjiL@f`;||1s z#W23r1$A38g`;$hM#In|91j*T#RezObU@NfF~*$CS=+Lm5jA9CebXc_8G7{4|g$+U4z>$4VuRhcekCsjYLX#0Z<>VW`dkG9q>R-Gx&hf9d2K zub+DJm3_}$$er8;RME~SS}mMQTn^VorXZ!zZRxpG%R*?B9M)e(=8eH>f`M=hm}{xO zalGU0`QtB69J)8!{>J=~Hz%vF9wGfwUl9-JQy9B#oMPvdBj%eH^g(0?ah|G5DJXH! zWa{GrJxk;`OoW&(Pym^|U^`wCffghFGXR+?l_y6~6)c#p+|=saDb5BN!>yqt9H_J5 zg%CQi`J1sMZeR!W6&^l-iKt`Tr5iWc`*T{}*+%nC;&}iG z;fRO?$?}T_N-pda1I1fn1Is3e|10Nq_Pjm)@_+f!?hDf z@&~s(bfR#}E6?ux>~EfY_q&yMURY@h#%RnV5I$wk?xK29Gzz=|va*4+a=C^Fa^}pM zh-uI-ND#8m`Yu;0=6^K>>Top!<7m>a^_`WRBAhY4OhN=QLS&W#bh1#>pkFC)I&zKp z$sitwXo`CZ-LCdUGW?Gv0^Jt5dSD@bc}}1sK@hkJLlQPt5gL2JoJVMPZqi_dNNC0| zK*DhL3t&g|P{#W=x?OG(MiR6GVfPnMe?Se1QZs%scA3SBM*r9ECXxjyPRnK%851oE zOMna6fIxb@(72`2&JQ4=Zhr5#&V26Kqp#nvmiOeRmXOzCmk%EG z&tSC&XY<&Wths%<`w){1SL(}*7csyG?}VU;^;}QB4#n|EH2$36FP@lkie26?9Abv4 zdR{b}r?;og?Xp|M6CLbr!ZH5guz(K70I(R;TKW3G$<3SjXiXim;;Qu4K@Xt2sN!nN zmaB)3ywG<1`O|GLcAkBu_rxn_x82!ab!nTy0gPKb$kUv_cjiv-D_cC3I=rWJvc2wn zZ{hecg(B}Gb*$4O1FAhF3oo^Ov;g2BUOLkR7)-g%95rtk=joI%y8y9TA zilMNy9lt;D#b-M{_naX$OsJeFl}J6yAC^`}Q{W6p(^>$r9R(09fUB(kqM|p0Ikh8) z`}Axln`tP3DkdD>N>o7x+@M}`%Sz}-I)kN6w+AhP-@u4?1j26|qcI}+ zAPqnS_T2M(EGf2(xN51Z=0blx!;MSb_16c=uY?|6wGY)#pY`VULPEXDDz2W)p5Euy z(mNnVOD-K&&+7}|;lbD@)<>pkF-CJOk<@*Yp(amYm#lQp_8m0|?^*33v*_ZbV>p78 znPwIiT3VJ7R8q=yoPq*FYIyWqGL*IY%E+;|pE>f@3x{8O@$k#f)m<4eIOYJ7W~`4) zhc7_|?U$tON8bz4)_ua?BzhM}#<#~|>m43hXA90_2?JUW&Lz}PaWa|F`Is6*;Ml5x za#94sJd`5!jwA@F+cagAIP87UH_n@O$(cl{fJtp~k1h#QFqVlKasK};;D<|w$0`ux zfh==;EO9mrSvFKjP(f`ALonLLngDLE>vYuw4Q8;|US819AvL@XQTs;IrE8EK(8uP# zLh3o$LikN#MLiY5E#MOHKla7cs4zucC=&|>>i}x6newZSXMD&q>%wROrdkf%>zMqt z8=v~`zwxE}-@5+ImvhGLtCfze0L%S<=CE!I7KDP_b?TT@8s76qzm zJP3yF;X=m2Xia0o<6!N|&dnTb>R)>9#ApAg`ni`@CJYRHA4`rj7v%Hix9J2|bfl@k zog!kP)PZI$5NZ8e6Q^`rs6EF^wZp6WQe_z*FhpE%u;GS;e25UvuvHc?%Hx3F!4tVg z=649;qHR&Cbs6 z`dASnVuO`p91^GLev^{=mJJz-h!8ZY=uxi-_=#~&p?`u;aBmtF4PFt}CS9zBb-Q=?UO4cIk<+lBuGsU5;pZC!Xg z0$5Z*GDTo1W94f{E7X~kGfAdUXLoFx*|~8vHdAO-GC49`J(o4T`^YEelZJNlse9nu zdeTbGj@nOqLNB`Gx%rAqV+EJb=bm%! zqlu)!_Wi@Hh2b!8ft$pWT`5m=?pGUw0%TinPjyPl?cwr`S^ymcny85zoY}5klHp)_ z50(VFZunx|!?l!WdJomyzq0Ws-|l#8>F&S$Y39;-^IU8VIEIy8eqgA2?cNOuaJag; zSpf<$cjaR_Zy9bZ|B~E6Y64Nkojxw65N`oZnY6Pf6vdaVE5V)UxlwaQo*gzEWD^%tY~joG4^mT95s~J!a*Corp2eaNOvUTj{tV){ z#;x(vwX@&|A)@|aC;v<;^5-Xt%eVR?K#MFvBwf`Co3s(s6RkuOqfk*Q4yp`%<1?hpxG6EW`2_WixWV8SbIE*ocunSDHM_ zR!b?a>*wB3Q?WTze}AZO?Rh_+%^wK8VUg!=63+%UMYqWN2 zvVLpOlE=K+Q-urXawxv#Tmz#C>n1ZplP&;`Q_>xgubqLE$u`pC3-2z>{OI)??+!bt zdI2tTUY{Svo{fe&U|9A$k-~~BCa_aR)&TIvka4s|#VD*r$ER(X0%WQA1N{?8>=qYW zw0^L!-9v|Yff_9Cyn<&kioanWcTBO-Rz2W;CU1W(dLy3)KPE8=C6K`W94%+DSg#~m@FXE@$JbRYBfGa0&xeA zKmMp-ePP!~Wms^GmFl4Ym|86yU0p!M?XxWXsj<+mA`6Vv#zKVA#za%Vsj0z*iq41y zx}tp)>plZX4~C&41|%&$5$jZP;{+RDfsM2e>PZY( z)8!5nR>9v-QyJ3lly0CuVK2 zlQBNNnI?Kkg6gva@_V#>u~YV=bgB>WI^-#}!SN3#OYYt**}N$!_)D@T!QVRstxsmq54 z+Owz5B@G_i-Cc&;W0}_{Zll#lPn$n;?xVXO|NDP+<4gB%eeL1i-kRqI4l5E=3y}ne(T&b? zuq?YfTzYp9=ci<&r+B-UDI5(ZI9C;_zS=bwre66AC&z#Krsm?gzS8HqOEafWoOx?8 zY3QhTOU}TkA}B;wLfR(tZIRFgO!%aV9YEAiekRDbWNpX=0!FeNYR9vEz7f}QUy4e z89m=qlDXVy1S1}LpbTgzmu<|{<(af1YD#?UuZ^@~$Cj-w6EI1aF5!&27z|R=Ski{Z zSB4tyPBq<|%UV38bT<@Gq9Auk1pd^ZiIzfT*-~%O!gWbaDVV<0>Vqqy$Z7FpGN;;1 z#;ezc+g_b6XD+dEx#883x(A~Li&rzoPide8MhmG+HZKBpPQ5n1^tha~R@+lUdC!myj#QfmJ;g171YoGv=!9NlKRmWC2U2?Et(z5FR~#oP zFDkB{H0wo7PWSYuS_H4yQ#z^-1%F^sg!BpY{%ReKCQ+S_1fD#7{LoCB2SoEO>;q1@ z+3Xs(D>Ks}X9w5%;8yWsD`6vmLaWH`m7h;GtGBtMyd!K9!F5#Js{ai>qz^Z@aQQ^u zLVNz=F_4jyFY1=8cbxffqT~H3hB?&ez#s8nDPB0+c<%Mi>F?it=P$qc{r~W@@!wh# zRKqc^8*?=);{R}U+0qH*f7E@JYu0i>{z@#<7NCHpLnwE7{99#*Xd z05J~RK`Pw7#Kp-ATb}+3(l9SWbK3z9c2@(1UKpy+-iUbMeN#bZRh@gMgjxK!o5q zaBtrp%L4k-K|qitg=Kv3apa;3dzxzRoG4l%#I96~K>*A#1;!wQ4M{bkU z6D*(|o{vE7r3+BVC0@b#j8{AqMUWrA)QC`t$XbDR2?jXvvyYlypS6Aq#N?!@$pe!~ zkXlIq@L|dyp639$12_jjJrsbO4Dv#6#rcnxFTKCjvOQ6|-dDbIT`48n7tCHOoV%Gn ze?4#Ek{f~fiBGcY8l_&{b6q8$xoI0(4yvkN0BzOerTw*`q3^u5_)oul|IdH(&A&dh=m7n{uhsMs%(1oR?Fk=Z~ljW)%~q^?aU2Te)u{X zt(Nh8E4$NIa%VtHF5A9UcDFZo?PkH|t)i{2+@&kU8=Y*TwUBUl^b9?ti2YPgx^a>M zZ}N9OKK1UpGCP0s%FAO7rmlK?v95gMLNEa!lZ;S;bRFB$?bS`6KW3r)iT9`8{da%f z_IQrxGX(xOx?cMA>xV77w4@S9rAW(KI16Y}?Hf<0FI5z6*yB)XryFQj6M^8GG6mzR zm7rZ`#YXe}!PbY9wf9D?L5y|}CU3+r-oRK|tQkG}-7 zi{3zHMW$&ZoQk7@dRw;(7zzCXFnqjuC;rD+fe;U=z?LgpCs5Ew&0Y;+vdl5DdLS(a zrUIPLTW{A>NXmd&yhISFu`;_w1(;|LRW@!mw)Qs4mT!5_E*&7naxSo;;vcFH9t6Eg zG^A1n^g3L@U&aA2l6CmW5W=$U8-OMg=jaDDDZutgJ{YyJdxZn!c;3DlAXR3*!~$U4xw|DuHQ6>hp@Rp(u%olR7B3X$RjwTN6sBD zUAc7RmDvmLKfd~fcQ3qmzwS<#`d?NGB!8^N8>Wh?-M-fS%}qPX<3o+*X?S14-m#AZ z;7{Yp$hi*-^c3tfi$n@ z`%<1COvV^T0#U4nL~bH_G*{Iq%I{LICid?zBy^0MqA|C^%x<-@?49_J^(5xh-n~@1 z)*gES=2+UI%%RVf<}PCPHi_`+|Hvci|B1#ZfbX8Ix_d^BtG##G!dCoJkD%qMYyhB{hCZ>Th(ec2g*foXDKHhCLXL`qTB6He#&#IYa~^ zd8o7q+$I`JW-nO~ANDxicve;Jkw&0k{;V<&AS1vELBg`1AmFC4>NvvHr$5`zL2?d_SYIqLRHCb;1Af6Z#S|6)6N6nR zeCPFFgTHyPWmN-ZPj%(+i1YU~4{px?(Z_9X&9uKUACaFbfuS^$x;`8F%pU{ZlzQ9? zpM}VRvxoQZ!Fj4X0}##orSIF13`~2!{;>VwNZI0r7y82n|M}j^y@Smu6U_IHCy$)8 zDW-g}+v~_H(`l0@fTD61{*U+I8-*{*7_r7-ey{Sik`MYPo zv<9Ei0;I;cR;Y{>Dha1e9YMku%|<;Y5~ZpyYw5I@Uvj&r`1Y;* zjV{4oBFJ68QLuR}cm0x0kvXeZa#yYkp?e0?1tn1ze?XSxAi)kaYw=v}%Eip(a|frm zz)}B2WrYamCI$wGhsJxYk0~Wf=e8qnuRQ!$e{kl5$y;CFJbHfy^T9~^pWNE}i5rJM z(Rn}$aPL%`F*3$fS*o;Pk;5C=a_(|trnR0+Rc4^MiQ5SlzJ^rUKO*rrexJxEye z1T(>vaW@mfgkm!VIuUFl^mVPSmrbwWh#m5k_z9({+U%xifK*2}vEEB2DFUm1WPicm z5@FtZD#m~{^ca-)A!C6#R2iXJ2281oGl!T)9 z`2LUn?vL*N>AQ`0&aj${xQAD-54|4sf6c~O{tsFJ@jphcGyH#!7tgdO{C}GA67fHI zxJdlp+n4%6cS;1qu%#*$^KtLh(qZP$oM*VkZ*&g9W#EegQ^)eQ7F*x`Fl%L$;U|O8 ztdSOLbcCs0L2Ic_o4%Sm-{nFvG7@HG-WZw;6cJg1|#}Oqu@vbx_kSbBX6H9Px z9PY^nr(-C^_Thm%2#+5nc#3{v&U1Y!MhU48lK>b7-${uwyN0V!f=`C9LgK{=&P!?$;UeD!gO2 zV|U@=AAj||zxj*qZ@)eGqxU&<#Y`%;(1Q9=E3!bPRSEo#nVdE-fQ%Db&zy%2xC&__# zXtWk})xAELw0P8Cs_w*pV>mp2MSkIWckxzt{ziB4W^cjjje@mn#aq|&HZJFF-pE+G zoV{|IOALTL*tP~t2||wf0uDCCE(VdZ8P8vA1k0PMD42kay=OB z^}qi4(YI%wy5?3UOY1=C{MmDHB!&xe7EhtyxbIvyQx{GEodSJIY$Obaibe?`= zP>^IVwaAiD##1Y+G=eg0` zT@$?hGyH0pt^QqT-2?d_$}pexC_OuZ$x~i;|ANzNuxpUPCK|U&Vd;f=D20Vy5C0(` zYYWOVA;|}ZH24)5WeNkMcAYQIgN7aN6jCSUg)PHe8&aI4rmg@i*aeohRPA<~=(*R5 ze}x2i860g*0F2kYlZd@r%j@Zz_*c|yUNQx?`ODW8Tc@y?z_zxf6tA2tTR&Z~alU;0 zT;a-b^Marn_U9U_X&hkPg1?SW$jYB-nfUJJZ~omM|I`2H&u4$OtxV;WAZ_%ApEVWc8AyBe_QluyP96{>v8gRYHpcZ31705&MV_stDZz7Y7NmLf)Q~V$#R4H>R(A^x){D1)Z;5S0Esf&_jW@ zX8O#?OSgqdCNlhY;Ag+i`pw3Xtjfe59uYIrVtSgD(a$muVy;T>#xYqZ* z*IOS=G{3og>I-*|y|vo>>WD}V877?3J$<@2T&8#RRu!)d6fKSZ%STOzgYXZQ5&ws|D4#65-CerXU9jGn zzj3{EtJ9njkOHegcEZ(3M<|-8yZu++z5cB`dk1SgVj_}U;L+eOm$Dev4Z(Zi+py!P zKN*oze(}S-vB2(_T|f^83uUOwAKe448a_VXSGD=4Khm$oQu~{S!Y4nJAQibQtp=AY zreoLAN^8z?73Cnea8Gf~E1k8EZ$T`NzBLIPv(C)rE!()nJ;w3)?5$)!A$R30gc%f; zGJo#y-0}S^ujgwN|G*7b!}tJ%67(eU|A`1J#!m_uEC?5k^MhOI&F8M15GNDTycYQp zVsAI40!e!Hp*TfjIHb*$na>ui)fcZdYfMrWu&{C+JdSS%R;>>l z7--ZobH2hq%$w$b)TbSg-vxPy6S4eSPphS6M2Ku@Z#K>2tajTtKwSqCTI<0JT| z&!5x5GR(n-o!d$N0H5(7e3ZRaUZe9@?YMPa5xF(yRZn1Pw04i`dr( z<%=0CyH=eVF{3|~=p4hM5eqlPN~B+LI|O10imcBI9}80G5TCjPC_0pHZsKo1I>t9X z3v5=s6ka+#S?-G}OJ^!}K~YTP<;u_%G?qNH*Sv;8V1hnLDqFjQjsmVhiQ8V(w2n8Lwr_-cZT*caIO zRkPMpzukND<9qM?&F?#MqN|;Zkvlv%oi-ZhiTV6tLc%am1kDx!ggyaB<;mYbsEqo2 zj`dclCtXLc$3*A$F)6aId~LP+`>)j8>Cf7}e0bs1VPt+rbEcE**{zQ4hc(4V;P%;Y zfArXEb7k9?p1jH-AvsYTR@&$){zIn~ex3+l>v{bpNlpl0^@&2?q7qM;U_EhI_ETC7g8NM)kP>1}^!R;R<@6oqyFKr0dSXKp6z(b(58cU7ev7;ScO zxVJ@w3}M~zr1=x(eX>lsxe zAQ?#@{fhs28yz~tcn~lm#$p3|(v&S=m1Nftfa>i&q9iu;tc_H;Kox-<&7O|Hm{=%Q z39Es%08XQb7u@@aER>-XMsu?{HgmCk4*3A9|A{lpO1#!sKK`NV~<1WJ(bmXGVnZ*-G$b?m5LlRI_R-k*CJ!P7mNHYsT ztONBA(>5E>#8q7bYdBDUp#9S|0O|~9m?NmYz|###1;PbH2nr3vu=7j&CxF5cEwC7R zw9*{B7C!M=gx5Kb4F`37TNMS>0Q7MFYH4$PskqX$Qi2(v{i=M?ss32>X- z$4pkpyxgxdq}zEVQh+8m;HD_>68cstKxvJfkT!q(&|EvN!hxAalPqYY2QzX6S=msD zex&m51uLFWD4* z%?u)Cd;aPr-{N^>9nZ?(X@*g(BbS;DIC_70zx&(w+FqaVjp@thvzE@XJI19?n`Y#D z9Mt2P#qfu6{Jl(=)sHA0hR^8>Rp|>P!ys{4Ams2m?wyb;j)_-h${+nt{}Ol$==j`l zYR4Nh7vEihJeWDEB=gpe`HVsna07)qbv}H10P=1VCym;N1E0IW-!+{t+`fLaURE

_6IeAZyxL2m7yKPyK#=PRO%?W2SHrkw_h_26jC&>uo>9+FhT7c|t(Y&~qFTDa z-pwFbFpq#Q!jnx+OZ~YAC-M$XP>mHCTYLF9VyQ2rfCCd*`=>Kro=V?4o4s!irzm~z zRHoix*GTH;C(~b;4E=J@EEDPjwf&x{oFi{v$zO&Thvr%+mgYRgKzQ0r<$Z|4SYmSd z)1Yal3^lOV;HY5~NqKP&_D&qJXEX)C6^b5?L!RjI@(`(w*M_0QXd%9buwV!R{)(z5 ztob5F`CkS)fEUk*D$aup9a4qrn0OyW$23}8y4F##N!)?HQfN3E!GFr;->^pXg^?vY zAozxm4o|=ubqn&BIR76lTs*1H7x|?IvMEhg``bfx4{nNP(0TsZ&#l9Zw1)i zn}rUX*~Cnd<0c+RKf9xX@#}!^}*eC9$~e z^S#L+APt3Etk~wX{A5?wlbu3zZjfYbw@hsEHBbmL(xjW)LO6zyFE21lwB9Hvb~Zpw zRcW7@4|qJIdQT8_BH7WCl9(}|vko$`%vWqQn3IF(0ZZr39Dh98{P5PgECaUvO^__)|tZ`oH()$PeBt z-|SCYzI=H3lr#kAH$KxxBri7vGThJHG8Re#I{0?FM{)sl#b*?0^#X`<7R1=e<%^){ z67pDHCYnvPW^P>S{q6%xixQ|;?(A=V;r^d}k4h^p&P;>grqtv%>{7(7nT)l?()yEE zQ$*crlP2RQ08#o_2bXwUP+*!1$oojy?=5+s{^Z)B zGg1``v*-{=#mau=iZPsLKX>9HYP9gqxS(k1vU(ul%)_YJ1oKq5$=PNyR+h7NLNUN6 zSs83@s94S3XcwhLDz{Qv(f6qyb&&!{U`^zN6NQ+iSg8)1^#SA+?=LqAmGkubETl#_VY<$|ZnbP#d{PY<%(YeVp>?3mV zSB<~nKLo|HKy25V&haA4)egKolV$A}t0;mpOViA|0bhp~Xb|EJ@cR-2YhS$?g^k!w z^Oe|_;a2Jqu!uiDQ4mHD_N|Q2Xjg_a-ePmb_Jzi+ONQn#aURTic{Ew4NCSLE5(c9;=&R6eG^~t-mm2aWPZkC3f2q!ia>W#=h08~Q zJh-EN4rnNiW5Xoxky`OTC@W*Ns{JSzM{3Dh86C??LVdyV>5`SxP$m;z_egfmn1g#* z`$Y@c5_(}{1$>y%y6W4PkcdP@jRX8AhLQpcud3l}fKT7o=D+qo|Mv3lJ!-yd`co*< z21lhgvv{-39xL&`X8k+~z)QD^#PIa7I=0Uxv&Rg7b0_N9{v4);u${Im<@4Q1Y#)OE z*^~Nw57*7)-QCF$A!UroNJI%^$8JKZ5+8)$f?+*ECLRtyH_Tg+DtV-~dhIF_@=JsD z2A~J0I%*$pJ=5P{r=FVJ>2+(u+jIVyr!vs^-gF!TaupWnq%l%0)B6T&t}5~q2hfFVsaOx6%~TJ zPn?Jpr)&r%X_%qa?u^nr7ivyX+5>Am!IV4THS7ZO1@|uD8xVzD=uq?y(a!>)Xr{;w+ynAM6Tf&h1j{nHK9Kq_IiVj$-V7;88}Qu-@1iokzB zQjin!Sc^)Tb_%ES{xjBQ#moy`-v~ohBb!WCx4zYX^sVvsx2H~gVXAohd}yg?qsDbf zMW`B2bf$db>Y=B)512uKcgh~zDB8aM(oih;a1qp~-QT}^{LLA(s83xx{KWNrPh3y> zTwgNGEqU%NCu)IIk*rh(HK>_IPB>@V{i*Eviz!P-QWwu0n1YiO84*T(H5XWrkH*GR zkAs7ev(S>i+~k?!9$c`9G9k8CF|LF#XUv`3J5wHhzrCS->-p{-YI*>;>KC*^$Mo`S zhD)asAa??TKiQp5q6_B%RN8oGRoU~MrN`fx2*>`3I+dhLK}ZfN#AZh$lsGhEh09lU zlp4>NgG{z0FIMT?A#Z?ao9<7(vrT9H$*Tut6Rw8D=4M-ND7h0T2Gz%IO-y)zHq95h zVA5Pi%EIZC#iNY%bOc5iqLW@YWJlb&2kXFkFj5gu3P4{p@=%;8q71eav9hH6Xf-63 zz66)Iey;3x52K9o?OPRhy0Kx4Hm)#9@L{d!1$t-@T+fo_3m4v9y#DoJD|;+%NM9~X ztX#|>Ot6a4fS7+ED9>eAz1Z~-W$-vfA>aPIpx=xZK0TDRTiIjT!9YqJ;K?+)Fz*49 zqgIz^Bf?MS6NqKb^S6maV2T}PJ7W7}%m}<*oK92c6BJlFV7p@4VnANmYfbfc&aC|2 zC$nkd*)HseA^KKUNwo#&|9UQO*5xpP$S`(ShL@tqR3J zErJNk-@~6)!(a5n} zCRD%yW#=tfK+u@@Pd!~6!r;0O6{L++TzP-s?Z5om%#ZK3-ak(xv-?&MV~j!b-aNTW zh0{~mboX-6!m$^-3SaIiBmszxFv0(6&1V?Sc{}hQk&V4`a*TizK#)IeIq|YeQq%%> zm}H>?89>AY7KkB=_80KAL*_p?ak=KnD*ZGgGghBiYW_38G)SP5tT)fx0h9!Rku@R|_p_3&mParK zUmgt#H*CQ#(k#GRa1u~7+4$Rs64*P-mjsnmJug-9d$*U$8pO=`3Wq$F2F?Ty16%Oy zcxL0+5C?ISK#Cj4dMQCI2zn|oYFKs%&Ut_s1g8NLm6+yhTU=*XTg=yJJb({4gbsYEVlpaT+sRGp|J(TQU()6)xdmbIf2a8O ze#HOa6Al+w-oM=T)=CpO373Y1U4zkvoR#oWXl{6Qx_G$k#acz^K6mzU=e8xN5wjU+VApE zI5YS^9#YIhSw^OVLIY1^s2HI#tQ)jU;qYg!XB-}Fvz3fY4D8eY!?ys2xP?3YRQ7UX z!J18!wbGwzQ28x$Rc`icDm`>g8dynI<#FvIWUrjK^}RbIKX|L{@qj{l_gM5?Izinf z3V|dWw(x(}#^PX{_Qkq^t#J{YD{-t8&dy2ax z+$1h{`cmV@Sjs>XJ?5d2()_v81&b&1*Ny}?ZzAkH1^iI##uk7;$qZ%mBMD11Y_y=h zpd2Wkd8rBGs`LYs8ClEz85f95kPck{Fh@p6n=VS9D$JZIOq*ehoX4I{&F|lcnL&>q ziQO*L#Ct~55>^cGF1<`~?frAT-?;zvU;O;zKmGC5FU?opJJIssRLS!3eY5siq)~Ue z@@2RAid3p31Kwo#06DRPUgV!Dpy@;IJ-on3&`MB>w(xlfU}_wpf^|c1>LhF3pXWj} z({U?|xq9Xmlsh8Vm1GuwlkrQ{K|?{MB|yRQi1DPBw{k zNF%ZOT)f2>68x=w@v_V%Y#+$GX3#_%)2EIIbjk@SASnH_4UVypPRvE>Wd|ADn|1^7 z$+u7)*5AA4g$}y22u1|+U9tcqocVzGFaDTRf-=%aD=)v-|Hd!AwEX*z#s7l?VOmbW zWuV#c_0AVMvtI7Zh5r!h3jPFW6kD7h%I3iMZ3WZ7_S%^L;`aCEyeQh=O#S@LBwrjD z$UnqzX|RL~ob|Ql0xWSLxr>8^fhpbDi}M-e`O8OVzKv-txxRTHpBK;KXT9 zu6-Y+3nz;gPx?5}Fz8d>G+lq4HSt;02dihz+%Yo^XML#LxnrC^Etlb*f$m$edc~V} z-B6B609d9N(*znY)1XpKU5tB2-hu{ch;Py%$TQYc!w1APTIM?YT4!V{fr3B0+Quqf zSj?p;;JbrG>3ahX0^?gQ?;0-F+nwrk`Dp%A*}#KNoiE@6Tb{C17aD`%*&7O6wXWog zB#<>*k-JcxpLi84<7HJ@u$8b7iQunb4tcK&)z1?(2l(RxhC&%P%ms7@jfs)&1jB@* zvWgDTNNh2xkkL#B#QB~0FM}8XSn2M!`y#yk2Xmd7k>C9=Z~Yn!!5k`e_Bc>N4KEt# zN<{vhSDbVD)4#9(gT8{YZuq!yS|bc{F{bf;y!=bS1YE%Iv*wkqhBx}m3rsnA^&9jH zO1t|?Tmgy$esOUN^xC71h3nT(el)Eg4;~alX-HRJQQpcaLMrbcVC83e&|)ky(R}Tj zTZQXaSQ0^y3=5#&hv%-OtXxW7?nqudk+yOwb>U>{{3*bQWC0o~x_!xn^x$}_v7-T{ zN*mI`Vi*3Vet=G>@a^!r`1P%^pFGCM^(g?4D&)2|`^0Cd!9P$aVunNvAIbG-n<0`2 zxun_CXR22EGe$aU?sXq~d#P-rQ|p8!BIaBBOBz0pBbc6BA^&YrmV&h4tT z?zHh1NPljqE%r?h z7EZr5*?xbho)jvVn6v@Nk2Ti>)Z{}>v zgQ0h5i<~&>nZ3=wOXtF2ZKrK zmj06Fdso!|(0jBKNInaQ(%GZx|HA3U{ONiqP`V{GrT~4pdokoY(_X%n8Drm}s*Le^ zo6FKU<7o`NhH`?^HW~^$IHxu_Yv$a`GmW1fEPZyW_?gM_@<)#^eEBCYj~@r2WDGYH zOrES->a3c-S-W(paQZk~Z|;j_D+sO^IOZ{1U@-(7D_T5Nv~VJ8yfuB8H__>m<+G-- zIvp&~9d3`C3s?iO5}q)1S5RrgwfR0NHje+L5m35=@%@bgo-B@n120tJtxo|N#lHBl zD)C?QBJu;q!C4XXj0XC1m6tJ4<0>|9+!;?n>STq-T!IjX1AFfeV}I;l{UCr;Ye_Vk zw^-+uGhgG+%&?%*edwmqK4aCO${$xpxc0lm^LQs#&LrN)pAb1&@Q-K{ z%|g8XA^tNxIN-%>XYQyi?XB+)`7$uT$MpVMHq1|zu%V}DNe;|$qU>G|5^2uz1=i3( zx1Nrdfhi!%uuon{o;p$YXoUOXo?EsR`@C$;sxuc7vSN#t@P+sTC={oH$iV&?0a*_l&X$Y+pbr&(`Nm-Vqv4{hi#{4T zvm95jaUR3gVn=@#Zk~6X%w+dWrhwML@=9xFZkZUlcds&ME?>TZ+7wPibCQQ!#vCvelajiONW}a-r z4F>p`(X6Kja}}a8$V;Q?sf)24UX$(_KmFw)du>8;HBR*(8!O_MjvqsxKK<^4Gw(fa ze|6RcG~0C^;$iRSV-u@1EHfnmetxV%0j3mhdbLxXCanZ|8~|PDuLG%@t;fY}d$Xrv z`x3BM@o!aG$=Zdyg)@r(yp^MdAOIrQ#A6;04!f{{EOJrn9R*C-1w20{%k;vDIpFgM zPUF@bXJ}wCg^oS$iPwYP(v=g4qxhfM3yt~9ZKWHhK>hW1ZybGd=)#xhuYO~>^^IP? z(GUTSRIu7c3t$SI!l=pvC}b&pM=LuXUtj#KyWL-ztXV$>{|9TpZEUY-`DXW%r}vTo zSTvkF-TFdjffj&6G70cM#Q%b+1}IP>1yte=#US`*>hsrA!dJPcgkKz`6`eK7?Y{mZ zWCqG9r&q)PM;IO{?VL%2@@Tati}s8%;JTT%bmgVNTC_tAro!9$fXex^EQ9cqD^@Nl z?|HCiPqn9vG^C8yWltTgSi5W=S;6$F!s)XXc!7fmLd^wa&)78Go9bdh_|c@zn9SYG z4%GPyEioS;gEcA-8YP4J$lquSW1Qj;jMtB!6FrR_g!~XZ-k$f@+N#eX- z(hK2)3f_|*@(}()JUqh|IJ`ZD5$T=}r)1$s=qwVGh%8cERC94&TJe~GXaqf-rsSgX z-`Ot=Ws(9s%Yvkc7lK)B(7uvvcCVuiwRGgIg6PP6ARC()HF!UnzB-|%<{uFoxhs0E(e!tuKy(DLBgP2-Yr{HU{S(Dh-n{K>1y zPh3jNT0Zs0zy7Bg)2FkSJA%6sy4ofcm$?8a)$GX|#)d7}IHzL#+|9UpWs9BTKm2g@ z=U=`0rQ2BOWWiTKsR@@>pCe1;EuSe^KV`BRW;=$J!^I`rmr4@g zzsg^UVvY=-VRWhHJUnX>SHQH{ni%Mf;~jYET$>F$9wq8IB{X1}H*J>aH|=qu@tAGE;^*CV-YuME`Rxxxi5 zyg(OQ3s#P*^P3*tY<;D>=Ki(v+ZXefJ4`2aI%-3 zK?F5Q2nld^W>A2-v$Oy(8M9rek$T=sx$evxk|z57kiwa)!8$-X1>>i4$J${mqA2Fo z%cG5Z`YOYMU@(LgK(^YotHq0#6#wFX`HFc2lOHO@)8)$-jEq?plrLTu{7cqO;XYxM zN!j{+z!y@egd2UgCM(K@a&&H2TSdyN8E?ul3&_i=_kpaP_%GC(3vim{CK~a-FDx^!rK2v)iYEmNbyZtOi&mO(yd@n^Rv-owRE@z? z^^+5ocHWb>@;}uj3j_x#nC<58w#0@PTxLgDh0oJiiRVcR$1y5%H?M$ej1}UIg|lb? zGA_OfD!gNBxqXf@orjD1KsM?4X#UH8`-`hz+>Z4Y zuMF7xh8*kqsKI=f22fdE`QV0U`5%6x_eP+4^&9sNPX||AGi7C7bUg`&hnHC>ubxg? zH23Tvq{R*mW=m&v_Qd7=Lk$))hwY^;QKiix1bZ=U?YV_MjpKVFj zC$1gDDf+c*d!Fn$V9LO9GjrnfWM3p(DKS^JY88JC3DxIJ03c?%~*d91(|mrR!!)&bk; z7Xp}CtRfR56OfDXroc*;8kF2VXUL0G^TK4B6d=pk1R?&X%oc*gqofaobu2Z`T{@*O zKmiIcKa8s2NX5>fzd1Bt#;^$TZ>r1fP5g&)*6zm z9CypY5`m9|)sV3cAjj_&d;KC$t1*)owuX)%YoSUauux|A1i5YsrcmZ$rGp`1$vD_G zco*U%X>hQTMv`K=Ob|U0&lnBtrn2 zAL|E(A>^n4UZiZ}y;Hq)w(;Qw*t-ZXAOPe;K4#1ONS+xbASjeyQ$R&hh}izXb#osI z=vbbVX9Yv{(y^@NR!_0^#}lNLh>S`9GE$Q09qOHm;O&rxP1e#11<%Tc(22s`X47NY zE{JJM&Fw4ocP=&FyLR-^0RBJd!xCXGKwgREzo&9%+Y_*PvyM6%z{}zez0~5i3h#lRU?TPAiR!%F*!6oZlx^~$_^jj7eM6OKRdm}3L z7Y2i88{-e%0eduP8+d9w|G<2(dWyGBc;5Mu?&>Y31Udb|)@QEe2<%T>wMxJmltZ8G zPQ$wKiS$!am2HV!9pnY^KU{sf_W%0zm*ogr0|j&T!UeI~^j6Kl(z9f(wd(fCip}GA z7lD4TT^-3r_ZJkwe7bXWH7TSYj-;A=s+?*6HUd+iN(PS)Q$S#{^=ufTu8 zI`ZE6meRZ3oGU;L5}$!o?dC{i4RRig&B4;v$J0xH`rFwXH@FZxGkL2u#s}4Rk2l=! zXnlN6H<7zim$}kVuzjNTUVp>wiRSy0_4h`KH?O%h03s(GW@W%ZNebR^@k_UCgBq&6 zJy5ZIBWLvp!2;U~ir|vXhN|t>riZ7`ymtN4`#m)qN6S}Q^elQwI29K=K|YG)ag6;` zR2&f!CqHSi$XkM7hcYon>Y-qb$;dQFGh1AJX{JcX^~J8Ch~8cfKQWZwYk3^B)8=T) zCAAXxpABy+nNMeO7e9c<4@2uW@*aE!360~p1Xwdes8 zpb#)+Hi1GDjzbC2v=HrV#Jc&Rd?Jo#S@(>fH&dwPVt>H{y*(k6wWg$Cv=OQ?TWL6B zjAi0sq8`PHVU!Pcd9%f4z9zqNpFjPxSpG5{6a_-h$QzigTNO5QKo*qrrpDOra zCQ9oh=9V+HwjS>u&Jt`TDc_~x0z7ikL)g$x3L`qr^p(a#lthVMSb5-o1+L39W2P2+ ze`lVHQQ)aJ@-|ynTT*hhJi1jEDBKDB|Ge4O+&TD98`hs7X=K0^4T+sg9s1(3^{YHOLgzaQ?z?{Uov#$%T@(kxOUkop-@#NH zl4rpJ%>S%|RJn2)!yo3KIdw#HL2eI}*fo;m&)uU*NZ0%jq#M;fvAK}}F6Hi9DdPVN zLySGs>CRAtq>0E5-YrVlc(qrgiT=!I3Hf`|b&g^JsA?zvCzzSx(5MQc9g`O%jtJU; zV5cQ4ZHfEh*ayaI#lw6#+*mUrbkn$r&j?6?3FFm|2NE7L5vq3X(8?Zb0=S`y;XCo) zR6<(m4NaNYD5B!Pc!2@&0~sZmFEb8O+2*abVQp#Lf^+46b?3R}s7GF=&!6ec{bUz& zIRJYI(~P~)NDia60>I~5l9rC_n>mua)Q;F@p6fb@|6U@e{ugYetlj}0j}fqZ?f z>k5BY)r(NC;1}qi0aAcd8aTPF@gT2Qx`AU~Z-rL=*2S!ib9@_=UP2a%h>n{UIAgh; z5GjGNh~y!H<};tYdh*cZaW#M%5>?ev5huf@GK7H~lX9&1Y1r)c!3`9`G_|+1>6MZ4 ztxmiS1&kR7jhhDt+N_(P=%FkQ8d?i)x`+5(w9#0x)!caJWW)A}M)Ci4 zTk&cg{71*osDM0g*A`%+VYf2Tv7Z z>HG80OkUx7OWoabmFvf=){nG4JiYLP?EIUZ#~xp)**>lv$XTgKUqbpy zvM)e1ejeaFm2qgEDOnCHA;T#ixo&iXN24xX^JKaZ7iPsHX#kDgqp{N0%@v114J6W% zj*49}EEO zCrT<8&k>67f(QqEkd#i@e&SZyO2)3PqSUQUA}k7sdRyg?%Xe-;2XT)+z%ZA@SUF0f=Q))p?F<}`wGuxrrDq%;(T7sgY3t*f;hM-@#< zqbZXvUCgNGDFt}JDcY&d#j(j!L}(Q2L&FU!emuB_c% zkr|)tvhW@MFduBCX%fk`U=ol}X6C}v__IBkvV8H{wS!ZQ4`d^9}eSv-fP=h&d zoa)z^b7`D~5vsR9pJv+pq8KIj#_{u$wE&1lu{bPYmz|i0Y6R>8E9Tv#MPirD9rWtQ zuORp0I6Xa>&durLfA<$NKl;|`_wJ_7oR3-O1QlCs@*;SIerK*+KJ&$UQ@{I-6K~$J zJ&HA``LE}cC!3T3tN>XciRG_06|PxCb+r0!d(FLLm^=t$SS!u1%w^1+eCp<*Pv1KD ziJJ#8Dt#!i+TmfXpS@C%vs7PvyT0;HN9Gbj2pH40ce$?-!*=f^-w9mJCNUHG2LsGs zKMwn%p%(m$Z(k|8b5$^p_cK+c{tp8GG|h!bm3?T@Hj|k6C^j4|ht>szy*R^eQ0eXK zaxtDs^6bg1)w7Ak3QYoqsjDyo`rfB{pAE8^4^n;SME$*vy6s~v4^BS(<2S~>Gk5ia z?h~(GsJ?y7M<$L|T8oFmW-RT3oQF5EF=e*oh!UyzPg^X{Tdhy$bj`kC5(SI6HDA&G z+(ZU>*G~M;S~-?9am>wPb(pJ<+1ijX zep=_t0jA~dWXZxMWcY*(Hes(lODvONup63X4jvRth+&f@tR6HSf$E@xPGuaNOQ#Mt z4JlY_$XhR`v{GuqZ(-?(GO)>LlynRskymVta3+8EzaNf;Z-V8P=#m-AzG8Ib<5*-HQBS zqc@rPvZP=y{5W^k3QxhF$-Ecm3QQ~Tn*4+3hO><%P`pfy_4tB0gkOY*nNUAbF$0l2 znA#acg1qJ6h~_OHLoF7&ymSHFUuB}a`J?ssZ!|o(p(y~MiTUWDM!;djn%D#4+w*4| zkKDb`xN*Dy$9OpRK!4U}VhLjk!g;~g*-y8^_dC;k_S|NNh) z8d!jOv64s~DLXWf|No2siZ_t26d>~N#D9N!K~9)uiP&0us!60iDY9(!T>Zv1)B@zd zJtOsdCYqmPM>Zaws8EhwV@i6gHa%37ZK^M~&v=pVw@(D9*}>~fa@|~D5&5$m#ES_y zRfw z02v=GMuef63NIZ61F1N-Qq{gkgN8lP!vZ?Wh5h(mnF5GmlB-a^<(2(;PCi}vpX#I+ z&Q{3_)XBu}2zyA(;UeaPm<_aZLAU^@lkClMjy@6dfGq@)m z9xRhDBm(aZJ`a+0p@h>wemH^-OJOE}0ve%W&_~sxj@ka%8oNjkCS&*l<4Sl1$Ziqd z$z2s)33nH&E4{ym0*)=6MSnfRBPGhh7;O`@+Nem}8fL}jRwdZfva<+@ABzu9I-0xO z0NGF&^Qa`T@$-`xh@h(y^*_A~$FpEnsf7ZHnZS|?k(YOSV4@-R@lgD!} z_g*q1(AfV4ZV3Cf<(gUs7BLr=1#&K?3iY(Q2tH}kWz;$S`L-nnC142Il2-i$SEZfZ zH0&2tn4(kaTwdmKX~uGqx0kw*pTAxW{IA~bC|+tQUvDelJj%$FmmT(q7FariMKJVZ zBH_=FR1atPIa(F(L8vr`CH@tWj3>NXLjkmW#t2*&p2f)=4nCOUgh8Z!pyO7Krp=e; zZx|NT!^{uas6LT}$fOw1%eaYQh%xSPX7gdN;IeYV#(`pNB1^|83xqYDxaZ5=5nAID zp+Zd-AqM+)69>Q1xZ# z^ktrIjAFv8fFiBgnkh+MC?g!Ur!r%)l)}*~&i_=6&k`AjPZTl5SiTz<)cxrk2#?5b z*db$Lu1ak>FC%ZM;kkiy&yk}gWhhxKaR^_#*bYycog-TzJh0dBF9Y?OO5H!7<7P#U zn91Ecm-FHbaapRdf@aDC9vJm>jk`d8B0!lhQ<^w?rjUwKwLP$i3V_uQQn&FzVs=of z$OrXMJ-5BqV;77f3hlgX<4kzL?Zp34sA-86@FyN!ZM%D}01Q49Ha_7z-;=r*9)7dn z*Bf@R0Ak>C7}i+@y~b&z`SXyUsE{(_S&>fNiF+6zw z{xocjW$Oso9Kgalz_<8D;o79ne;%B#IkX@OHLHZKSuY zd=+gM1lw;B^92EoOteL;vn8ha`mCAivb9!YP>~srTC;E9OHB|Io$>0d>5hT#eYE}0 zzRLClD_$8)4uA7Ik4}8Jz%3ben$UPw0mi-01EiE2SC;?uyWjawe>wN_Zj)EiPl_;+EoXs1jK+{yGW^*LdOW9+VDArJYkhTsZr7C7-wWO0v@=i0U|($r ze275xM6QN*l}GVY;W}7cdAA?0Mxb+?7)KYZHsOe>hqITMmedriwSe++7aPRkn(bqy z>kW{0@#k>D11D{<)(Iy=&^s6xqAAh>r%tqHOm`?h2(n66Z~FL_LC|(tx#f*{p9n5yE}K!dYo`IGy4coE#YB}92e~T$lQQCZz&BCv+<|X$Q{4}eg`vzW;< zJea8CCHxAsoU8~9#4FaXvY`{r@Kqo@NI08nWMIC& zL&Ji_IQjZ&`~8*n`%4$!e{kyU<^1LIfCAS?4=8I3%OD*Ug(Wp=iGWSCY2=eb zn8wko65vR_4m14OfIGUpxmXG9y2Z2$-epQSp0{U$06ER_M_`u=dvG$_C;?SW-W1*y z=LIH5Gd7fkXOv9A0g1ji(J6%SGT?%y59Z0%&*Y2q-pM!S)_?yuCx7~-Yv0+feC5)< z*`i1R1a6TrV+EW0;%VXqSG0UwI{@2{=Eb8oUJ2*Pojbw^4*26A=*P_~nLG%Iwf8Sw z{PJw&)+J4xF@*6!@!Co9F%={5=kRDr$x<8s=ds7vDq~+mp&g51bkLKk6!}Nh&-|mB zr`7+MJnfG=GsYT7U+JN!u@dqBh$(;;AoxGA0xl}KO<;hJK{RTJEWH_6oN}6IGlpK z3yaWek^)AfL}v9Y*_lTJDort{a!|GR_UBnZ;QuOLsRP*ZDE^r_gJ`5k(9p}hSzfZI z6a$k7Xy5$q!=^{GZ5FJ2{3;~*)7M~A+)DGGyOI9f^|a4lPbb#%j{{pnA5u$$?v0@* z`D4_01{FNUPdi{fuFejmFR&bRmT(B~pA%{*4p3Yaep)1-SE=uSA#eDCGdV5?GYxb& z51JPe7k)xC1p#qumcv29Y}!voU)Kfb8uUTRelU3cLR0zL(dvz34R=npK0IHx*(Lx+ z&t+suf;1Gz+ejrILuth*dAg=#siAVMMI81p8vNlVr7WL5ICqk5qp~o2{&f2rt3Upa z|JDg{-?=Y(Z=6C4x37Rf900CRj0j?QJzKYLs-@~)|HuFSU;OYt|LguAyj!$(E7m?r zQk2EPrz(T@^7Uo^Zc?8zR|W~uu=u4uk(yTg@!otup+F@cpKD6=)42zX3>kLhO1966 zEzk87Sz-Lit^@!0(%vU-9Dd@)UWP&}n*C$+8{moZyKp&LjKbBn{FPQ;m#iMC-R@|< zd*<{T*IOT)slE*YWe8kq#f*;9<)xk@Wcb`I+m=007$$Yp&7Zq<*n2BpxkN4}$Ouq+ z1f7(RV;=#qG)xkvGLj~XwYsX%cyE1%o26=0dNe?U5UPYG3Ul|dp1|oM9&)Ms4zEz0 z`@dmbsH68S9G2*3aV*Dk1-i`T>XhXomz>Ga~nI2ClJ=aZMqn;WR{bvRa>tDk2 zcG9MgTwyR6al9rN@{AUU=Q0k`i|1VU7iWaataYv^*ToT|65!awL;P8w-BSSZ?)r zLgCnG8;dLL0O`f6$4qGf1(wf-B5XLWm?Ia1u#o~cu3+n!Vq5SJfEPV!IM$aKH%PBO zl=(Q#8vQ;oTIx#a{<$EuJ9Qmj?1!#s;^3UYunjNMd`un_MpibOM3F>);fjec>Pdz_ z*;7riyzKGF$+u_g9`vWp9;ezM=l}|Vdc6Ez*3ESf@JJ#2E$F*g-yU<2pqVe*eB9BH zgUO+>DyuMMs=Vs%nH%3+sk_q|wg%JX>VF&|@n19$9IUx4U2Hx1_^S9{wRn_d$tV*j zZH;5rX44b3yMDd)*_Uo+t185)hC=U$B`2rOS*AB_kHujEXDlCbD`ABG;Gz9<| zjAhEZXa|O~;nGpAcV!zXnl$-S1r-?1ux+_1!CSDWn>#D}$N75fO&F2F!(>@27g&K5 zz**u}#DDQN$TnS3#%m1%b+N(;yl<)q%ukq(N_lE&L=>epqdB=gHZ@ZblFc%U=A58$ zjy+;_X+{0N6aPU#FZE=GDlME^O-YI`d~N>BI~(`@{1483VdJwmEfgr^Jn-zz%-x-V zBkjH!R(sHUZ@`fN#WOmq+&t27=Xmp-lK^csZ9H*OfT~ZFo@s);i=wr62j>3hqrA-% z2}(SDR^Dg((qxvX6KmB;>;_5_iy{ zk<87-v;#3>V7w5xiYj*}))_&TueKL0x5lb#c8g9Z_~t$R53=r4XU^4o6_h_R(&OK9y^TI7htx{awy-oMCE zK=`zU)7L(}_Xq#wZ-4tg|NG(Ze`J-gtfyu0>kuR`l-ybKqo}4V*NZnFke5m$DnNZx zzhZ*}Uf{aH;sE9_a9b?#?33j1(W3fPjffbZ=}!B#O9y}bS~6=^PDi*#X45W|C*5VS zGE%{uzEGBqkh54V*KpA(T{~KL=al$=;oVzDA6=|iZ?{vda9x8Raag)3TJLOsXL0Xn zJ)Wvw4+!9*IcYG2vbF1mR_68a8R;MfE`he;joYFXaVcP&vBOUfzrYWZeULR|73-bh zqdt%Y4M5}3Q&0zoJRzvIrG@L4ol*f`A7Lx5CsZN`ff#SHhR((gkje_pJS*^I%jhVZLF~A!BG-quQvODku*nhl=>pT&esvB z$5LaZBjn$|3|~Zcb2d?CY4Z(7;+lkybcrRWJ~$VPgLC;Jyto9ga(R81(k^+t%&=8= zi3OpCcPl+>0+eIyFZnYVX6@@Mm&kM|*b4?dLfoFoe8UbABWE!@tdNtvRq&VJD46?8 zJ7Q!3Q^E-K3N!qf$(RmY`Rc;4H%2SBF6ONs5&XlUXgb!^ikSpfWlL=*Ub%ASty}eL zC$$3z$-)|jO!GH-|8e=#zfr$CEI@nm8}D2~!Z%1oMMUxu)fCs zP4ft}cTKomS>JPDf=BcbPSIL>H>-5*92ZdEuByRi@w-%#$_ZNokZ@EWqBNLGu_U*u z^Cesjc!cHQY)OZkA8wEL<1hV7WmSTQgBTej8)5%f@!y=(nHjSAD8n@Ex&9=Tss=#- z51So?e3NUZ*ax^^JhPv@g(jVK{`sue!TLPjq%_8={=!Xn4W%srenJZtj8GxPp2VV!R*##t$f|m)NUwZr6D3jx^a$v$ zU7~<5sD5VPy7OnhS95p7Dp)0`yFepD zl^>j|@UjzUVsCfnKiI53N=J;?k76; zAPCW&SsBU2G>A!kc?c~9YnSp@Pb*8*>ftap6~(jHj#&gy2%#4(vvR97d$C$)L^yzI z0&Pp1J688#{I!4cCzro**BClXcqZzK*DvqwC)KG-pE}8Xf?bC9slP~@smzIs+?2D# zRtWfJM3@e|vU8#8UT@9zQ0dAIK&T#nZ%~Wbr{G`|+5+RpYUNxFPDG|%hG-s1;}|_c z(30u(1nR+(qV2OvVvm50nM!DWEb>bXAOaN^heOxzw4=lb{_t?mnkUQKD_lG8A2Vt6 z1u#T+;FJn|utehk3$TjU&zg*LPbFc{^7y}jJ|(s@h<>^)Oy0GZ%Aa-yfsnXAi#QGm_KVExRwUQrucIoO`d#bv|=+hU#tA( zS!jvkKV}E6`N~oFKL`i~hyk5}BVr-y`_Ugx{945`;{P+}lV0k|qc|&HJw?E!?oAo2 z1OY_~m~Ynw?8JXY(5dR2p7iHC?azv3i(aC7ME=17C(RT<#tGgyii>&r7@nSWv}%k1 z8~wej`n*H3IeqTiKi)Ul@$yL6GqOc>sHng+(Rs5M(`JaWTS;1CV6=J*o@2L*0uq&) z{u%-d_}bN(78Owl%}S$BpS0>aR`AYa!FJQb8nV_DleCIEnS z$W+Ke=s-bXMJ4Ue5YrSe#sp5g2h)4=vN*;s@&gs#F{SOv)TayMQh?$Lh~XnU0M2co zM@`X7jWW%YB0qayisUX%b{_UUq6vEdVfG(OBDs+pW(HyM3^E#>bIutZ05ozQ#73h7I)9yWH*%gF zcV>4s4L54ZrM1hYmgI_Bij-ulXqRNlDut3{msDk|{D;2I+e4PhRd01Q&|i4N^PF&> z``qWXXD*e0<$Tr`E@geGJMT+pa#a=4^((LUZw6YtICPjwmesT5VYsw3m@o>UvO3V@8;tSKI@0`7Ka z?)}TZU$A(Vv9*R>IQ#FOY(Wj0Y{U%bWP_nJ*`f=q?8ezWW38xbov-)J{?WI(zyJ2W zw-!akX=4XVrcdsDFx2s2?7?6BPe1$X|J3(;?`AI?r-6p25!vH<%%2`3)CjMpts&mb~RI56A|$o{>VobSdr2-MdBp;sJ26sKyBL##`f!cdtqP zd>U_JsYd|0KK3!RJ9JnRI>1pWgFdCtYs-?h1kFBkwsX&9SMJ;?G8((bJJ>P%T@+n* z^Ng&}d}lu`Cp{+KQn1)y>|@itE{Co$b@ucHeHr)(b#k%L`^9e`DBLwr|B|K^Yy@49 zW=X?HH6{#{5^x9uJDis&o&`sJ)3rUgoj#v!r-og;a?Fhq&x2B1AC6>A9r!A-NAhur zVhP=e7YFLqCY0MqjBYreVez9KZakN(B2#zgs_dh5^@1vAh(8;)LKtDR2zDevD_T9I z22r?lgyr;H0?!#M*6*N#Sva>}zGDfo|I!MkQoJ1?(uffNA&`sy)cR;xDTJt<@K3ST zFfXTVjwJiPd1$vB!5Z@xfKLK#i9bWwL^>S3IWv;7GMGPi02#xk05ymtLskMYTV;Pj z-lry2>=QU{4^$wXx76VYvdr8BEA9SxSk^G7z#%Fsd3=&G@tC+m?(9!8ju5-(FBUND zk*?0-?bO)&&q<6Z1O(24zTzi~_paM9de z{C~U@b^ zipD!XzI(JR4aqQRBFIj)>+sE3d8P8kLdFD@byG^a@~8I`>Upkjm%6RC%Ch+rI)e2n z%TpLk0vc+X5qypq<$$7ZdL#1ZF6Nr?7sfEKa2N@ZJL40Woun2PA|AWPTJ2WiLRn2fZ(=5Ix>E3Dcj1?>dgHHtdFX3%w15Ek zVcRtbpk)r%nq6y-7~W9={RPn!OP2j-tSnj&V#{R1_SyFQ)sxe|`ug4neTUx|nEUyg zfB4t`@jL(d-<|+-!rBT z)IA!x@W~sm{j)#$*1!9wi+}jN_Qw;F%5b>7WQA%(O)vCkM0lXZgA0~r59DurB~Qch zzSn17x>`}ZbfoY1-lQzIbFO9kB&Jghj3{kBG@Nr6yF6T}JzkLDGi%0pO3`>d!Hwtp z2_wYFq59Rn%EhYIM$h3tJ zE0DD@L}E_vhVVs{T*r5*Dn>(-H8x_zSasP_Q`Pd`+O>{~<-O&K%kx#J_`&@ctORn} z_%=BF+3#WovAVbg`O2AqAVBvba~)4~a-PTh#N;2(RLOS-XG#Z z$_<{~bAzzBm?pz%ZXGtvJy#9UWeNgWZyBx>KJ;obVCk<29q4^BCnIN+IeSi6a2q%@j#X7U_iFs5E=o#xxJX2&Hne-JM8Q{}9%T_3bTTqqImU*KW44A0y5J<@ zlNb(C>!X--)&s{l@<;wUK_;1H!I<1Op=jpezXeHK7Xz}{XgR86DBBDESK7G%VK(D0 zo`GpA&v_OWvjoR2)&E@Q-B#Q=0g_Z%|86k`4n!wXDCY zY~@Pv%K1$Lc`;DnY5^bTGB;i>ZhL*a>F#jO)R7}^q{e>wcI85E_UPHHu@mJBy_JiD znW^KV;+&aNN8Y>J@?fTL`Ap7YDDdnU->0Auoi*g9CB=g=@R#uqKI#;uCV8>ItY*tp z9bt;5#{*Y?c%$*=D^1s5Isg8`xBu;*|IuIn*VSMC^whf#y56{Pg`3=8jpgAh%tYz1%O685O;_@!FAW$#U6rRnA4XrQbzO} z7GYZnEpp~7z;4b#EhDHw!}ZX91yF&I$&zx+P-W?Z(nQ#q#Jz=3BNYnlBQq9Z9efRh zN8wTpn$A+3DoK#u-13z(HLHWxRcJnpDVNmKL=v4E9|owjcM2De=1-h9!YpU>FtVb% ztvA_gLS|u9^c7tmUdGgmdp8YcrO!3T9JH99NN%D4yHa@18NvD04kYOvuU$6B&{7nK z@RcGopP6NQP8);sK+XEQ+0V$97>F>0shBS@v9jK zJTRQJwSB)`xA`+w8^7HCBKw~)QrmR<3{B20mrL3I5a%=qe&zuCUp&6IAkqIZS8+2q6W$*5?|6gABp4$Vqr+4C6G=HUX92>Et0A9KS4zvDspT~D9=HnSM7twh4<7w+cHe9L)oUlq7LHagoxb?3>#zUIU%dP8 z{>jX*KDqL{Zw>$K1t#WUY|b>wA~MHvl}9wKMW0s}*|Wf7FvaG^w}?ZPjAhbH9yw`Yo0 z&Ti3W6|)bjp?@|qvkX^HpKXn}Jr((#IwpNQK7uB{iYf#^Y#{b4TRT;G{Q~V5YtLG> z2pLj#*t4)69P9B|^gblq681j<9HLCm3uuz!*`t8I)Ux;fk=A>M1^ET@wTj5=b%dx+ z#?V8+W4c8WmBjHD7bP5G|J6*Ls=feH8&DKBEs4ss4iyUssf1L5P0aimRRH^c6;k&AxEG|)}KTR z5(hE18-l=-On~Z89EXal%|!?_luJQ6dIUz@y+S{M_CR>i8ZQt-A-M)Kf(OL#R6Q$o znuE^NA{Dqdc5CX?O&mF+s=AtB&Psy~2%ZZ4mMOIZ*1O1+cD>&J%GbwPOKK9TEoo+4 zj?|9)_{J;WS+)&5*_`PP%u?C9dz(Mi5}O*eK&@x041eHdx)Z6qXHyyKxy~m(9PEI9 z8(otn!J!(v*`huC3g1NmQeK~dXV3OKX z1DdQaTRqVH;QYaNhR%MxaPC`62i_XM0xe%XY-D7xKtJvLDy9O>_#+3#;9V=fCl^S< z<6!R)>Myx<_=~lhK3BOZO2B6_cU&!LymdNvyp8>*0>S0 zklSPUd!YS#_Gx}zEr9qWAaAbk!0-HU z```h|xEzPrySV^WkKWuoRFpea0b1NP+Occm?3Tf1!}Z8+v*8}c*8T&}_Eh4+?HsHr znL8}$R&--Oor!3NLr4B$X>Bp4p1}|HzKM-wLWhj_Y;^1xY%n;U{2iBJvVi18;lML> z^W8DHz1oLLt3<#q2*I~2iZUYbC=F}IQT=fb8GPY{D!|6xY~_G;F#nm0Sb+tZawke3cqvMrrIqIa+6_Sx*&P6wc1_e6(HY<`}#lm2Y>L_|0M6c2T>?y%@kjBpKBb~q7Hp|LH6Nw* z+v84L4@^E6nMc_aS=2hQ>jn8rhn9^g?Ibt1Bm9h@6C9AWsj|uAJZ@Hf=WOYgsep%QcmbLcdbmm# zyV(D1dR)WxWS@(c_j6nB3{Fwre7k@j;b-roD@WfSXaD!Td9~%?1^N;{oSSwpRL~T*@}(7QS~JIZwh4njgzHw2iNU?1{I*m zcE#UNfx!R7|4(%O5sJbEnE8nO*;iy_K!87e1^<8h4|0rN03}yew0`SQ3k=8Y3Odkm z^Va!`8o`u546Gypbn;uj$XM-FAfTiNkoUYWIv_~m95QzzXDWjEOJiBH=eLivZyBh| zo2K&+8g6__L{@0Y1N1jKrMfmF)JQJ?ek^MoL)%e6hjjb4sW57t-i-y9XzxHrV-{6V zJ81i7bGU(z5pd`YnYbiuD^$D)`P|Wv{gDjX=Ic7)s#hTpp|WOcqkUe>&gU>9q0TIV!Ifp?pC?bm99qg5wGR9LzxBwlKsnmMd$&Zu9*V$T2~z4M$HIn8;+& zd~M-eP4Pk<;{ZpB!nB4g)1r-tO0~e2B?}&_`>e@@{deX8sf{3q#8fz+?*&0q2}~&f zA5neD+R>JKgHhicFe^tROnLtF>E&PjxbfaAk}Po`-xM`6BIk1fE(JFuDRYEp={NW+ z|LBMF=fC^7?D{1tZ8Ure7B4m3o7($mdiQYWSI=jC>Dy3rkfcZ_RjWd2?r?>J+@GI^D{gohK!<5S_Ak z`70fQy#S6T^S4gq&;>17*}M1NQOyXAw~sX3JzRdH&6%^eRz>t^ps|VnuNLG@9xGZn z1vrf{3S)JFq70U5Qv$pgrs>W&tPqvTXNJ{Y3j!t`2{j&M(J*DsZMfvAfiz_ctsLlZ zR_qI@!Wftv3J)346EsGOArFa&K#+gFIKdL`q0)n&6Y(&qH^U#b{SF%|nMSS1RUpy` z$XR|3yxB`tXsA)}b&Te1>`xB{eq>b@F?Bs@rh`B_^S~a>b?PVWs0dzKa2a_g5cz`nJZ3o+*_f#K3@n(1AIBW9Rw+(%)&VtBs~av9XU07@j3ZU*5|m}Z@^Q9f zS&TWtQgYv-rNTL@WkZbJN_<-z5BZ}cB{>zZ;v^o~uNd{ORO z)B+Ts+5gW$jJg+255WP;6pL>HF?-2h7+sDXna{AiA z@E$K0hra;h2r~xrH2gj@s{Mq%hlZ5C{Dol+zmiSnXiIcE28hH{Eh*ygDJ8+40(xkK9LR^8d7~zGH>zy$c>eSO`G}co?7y3@po0<| zZ4{$z3WA(b$o?cQ0Pe>HfEFcyv2zi1;^dX}0|io<^+1g*;WwlG(;TbN!;CBdOcYy2 z??ci72m1xLKGl;6(xLfde$Bi8{%2J;PwO?{M5LuHZ}b{2Z;hchFyqk}6tF4L;Y5#^(@=I)Q$Q;nh~7pP zEUFJvA^sp#lR(*4DzLmj7PZ-athEQumIp^z4>~;O+|K zSSJy3?Y*9y1!SSn6oQWhFxy)Mw5(V@*75cPCX!|)CodQ#&d_jue=|MIwS7d(OJ`e3 z=dJt(b~1O7+^g~dr82B1Mywx3^vVDGuk<+JZSoOuN)yczE*W&mlC8AAY^9;?&LO&O z#YqAcg?QOhYOm4iJL!s~_J$Y{xd3gj>i8+TMj>j)%7uYSXaE9HZ{e8GhVfYB;DQ0i zx}-zyVolycjh1J6%k*%-I2z(&EEu3q?vS{}x;Y5vQxq4%v`Uyf3qCHzD zvojYeOnb~-sZmpqNBBl>3}L#FT=F0mXRIjGmjqF%IwmM;Ph*7$nNp!3SBSk6Ocg|+ ze?f4?p|JBDnd)A}{bQmd*FxsPgDbhwhE-08GJCOo^SF#AFIprt1CA7#|A?IxsrMKQ zmIK)Lu3#F+wo*+aM427Lp0RrUI58Ut&nHN6oq!{(JXjD#O8!)OXe2>Y3dRgO&U!8- zi^=zyf&tBg0{+sqgU$^A#T{e_Tn8IXC9qjk+o>Gj{CG{(_2V@+J<9WKk9(AZ_q{$) zwsZ*FK^f7?VagygS*hytpNzCWJ^}Nw{n>x2$nC!~_}i6Fe4*jF&sS_#0)FO1+Lp@& zrE>@9PSf)b6`*UCl;6rHTgxV!3vpQqjiwscT|fq!7R6nDgos>EJ~PYmv;Vjjj6Xvc ziUja~EIZ@3y7M=6<0Mq@!qNfH0yu-WDHlth@7_9n4vTM#;UI%xha9HfCj{lb*Q|4W z^oJo5)@Q-;`Rdo+sebr+&cevn;SN!g+JWb&dJAI3*kn>9s>~oTU*iD#U+leu<%~QK zCJ=tzaPSuJY+n)oD2?JQB6P7>|h?#4NXw?jW%ON3PbPueB}Az)%BB4^Sr*wj<;+ZWQlbou2kp5LnfqU+76 z>RV^59FAr^)|Dg6!PoPMK=y=`<1vTJwGa&p^5;w8Drg^tF%7b@;_o0FS1-OLwbx3=6leB#aXUH6Xd zdvL7nR#(f-a0Hx!E*M@wDh(x8bjX-H+5GC{?Z5ol^?&grT%A2L%`qN#G&=k8=32<$ z)LlPRzqarE$KA&tp+KLmTJ2z3)g{&PSPW}#Ys&QSfPGjtAUUJK<+0oBKl3Xjum;?U z1T})WMPIP+!?lasvA=Y9;gGZc`SaBfdk0!3VP`d5&A-q;v0@~8Mq>4s*twOf=bG;f z0pC#B>uz2NA$nb$Xtx0Tu@EcsXdLV9b?!O81A^1FYK!I1b~LQ@*RPE3?(ecwoSrcV=c=P#Gy1?545cHy>=s(I%wUn=PS<+}}T(erqw&7OJ zH=fi;wIY6$z%+afC!eR`ze>EYr4XU3usrtVz49Qx!)2z0QC9nr_rCk5Nbb+mD` z7!)iYGqDJ{6gXpTdlzZ}_$Xm%u1h6^{nuN!nFfMdz;JHbXi))z>okqN68{r{^jHS( z5S+}(67AdAbRo1$R1iNZvI7Fq6o4~AjbY60h=_s>ch0e!5?CIUC_*N)+LM`g&>`q6 z(JG8kmRbC-^c;cTWK3`lFlW4+^aO=}j2(n!(X&YIpmLJ%ZKfk_E&p4Ucb`x;1&HiwKvc1f8!cP zQ0Hs?grijfKpCuoR^rh794InoVi%O)YBrW54Fq^a@$09*TEF@4m2dc5`6l-NiLNc; zf9=Ui048B+0Z8nBW5r~1`9u@@pEX_ws}cWaj@J2Ui2Qb3bU-mh1-rN}MjeGYja~+G zhbd8`!iK0XTNi_X2XSm_nHmA10VRfo(S^=k9)$du=>0q+W>S1#5d+Q(7(8dH7kvh| zi?;&S6)s<_dG)Q*TX!?(dW{scAJxA+IHr}wV@7N-dx!Z|lrcMi@fY86_i%ghk5}sA z5qPT?5P@NftZ1fC1aBW$hbt2GlxVfC2spx)pNhoL!Syq$ zHaNfI;829kQQeEKmSEmWDl=yH7p@(*r&wB7)rVUmWh%_j3)@)X~Cq~0U|x!!6mCP zK}ONd7VuY!?p7UNBOG!{Fz`d~-VoL6JpJ66-Cyb5o;7x;^YO&j|IOb>koIAVt~F%L1cg`~}G}3t!}-Tw3%24HqQv zR1NeVdP4?HQ?`5VpQ44BY^B*P@UD;ywS-Dnj?~<_P0iq7OG* zQViBXR#DFd=D4@(JQk^?uA$<0~~V?L2a@&OBCz_ zLfK$W%2YO~x0p6E9JDt`LYN?aE&6<$R8@$}`Ltj?O=3>wkTnnpVa32h=q*2Ex=Khu zXIfndJOxX2mR9th-#$`(a~~IAfssfOJ_&LFR>pooiWpUXN4LIsUWm?6Lx%#@0TzwM zba?T9DlzljKy%(HfcdMSNQ&(YBjXUUtIdtVdFZpXVxDgu z3hf{kz=qXD&ZG!O6AD}%rM18l=r@Y`P<(L-CKHjm(PFZwX4G1N+P?5T2oIu(TK@o| zBOeT%{>Du3Ki?gyy?v4{ocRCnyQ9ayHUS0FK_gD^UM$e;$!bF`*ncR{4(SF2ma{Cdp{^yo8CEcOxX5vU)^&=3Hoc<|EyX3Jwn78mTS?{)!K)T@)u@y zPnaZ99<|YtHWYmY_rR0Q#h7RYG{Kh;%kw4<0(sn3l!M>~Bpuw(4(}9fNE00LdcSi_ zY?sGDNEuy<4jVz{fblP9nQIe}eot^^)e*peG5vGWV8LkRTUTmgioG2~BYtDVfCi4J zyP3R(sU>J6+%ZxAaw_DM0debWgTd?n?Dw;$Pnz5Q`HL?-d1;GhS2TaN=Lc_2{``Ay{p&w(yx*&5 z9D_(lm?<+foW-R^CGJRdY@2QbxJ5mJ%r6CU9j1257|I8YGQz*1vA{J1cp|8aN}U>^`ocXxper|Q<tB8tNe zL-+f#Y|4Y+t(hPA_h<+AH)?uB3(fjapS2}K-)^R0W6xO4>Y} z$q`Ug=A_gPpe`^FW53c;Or=iD+~-m`krx;WpC}M=B@$0utcsiabRUc2BDEPN%bXuO zdMMa*K1w}0rp8Q$Zja|ET#s_hG#^*N_%pDwRL>#|^-w{@twU9JPq?=>7eCGvv^>6K zV#_XU*i^ypd1RhK6?{$22Oht|#mM@l1`4tT^KHe;2St4h4*#ei&i}gkoVbmgu~^R& z$t>_3s4;BANI~KqEmXagP((&KQX~t*w=bA#)BGj5Q=Wi(KX)}|j&Njx*rMtE<~-&t zw8eHv=85YXwy)7aV?fMW!_?vTM)ZQA*6$iFGdA?d zdzTQ!u{5=WAmsw9iT`i8oSC-L{+Zg1zg4mEGo>3)fHoc7$>?qCFKxeb-c)yKLhf*F z$#`A$Ohaj^wwUJ{Yswz2%cD#?T&)(M7Mx`cCT`o6beOXXXYHd|srS>d=|Bcs1FEBG zg@7RtU{jxwqX+iA^Wow5fAUP~5V1Z8kC`3$D?`n1f9Jrrf8O%7AMX3`9~}PL4~uTC zY3&c4sG)jU47-}U)KhWy(azMV9pkO4!@?>aEx3-uS)MY-&5APMfc=b-wq3(?bm^O^ zJeELcL3~(hJ_oDK_y*8lLiP0oEU0- z3Ly-oeqpg$crXOJOqiiMtOkuumoZ(U)WT|kf8ls=7+XxRZShz+zE`55zU(L5LpbL# ziM0gzlBSTy?9JIVRC)5Pu}}W(pMCc~{!`=6z~fo~SomlUH@CMp$3+ETtFcl1nbdYU z2nm8Jxi%|*b>GxRRa&KrqTH<$1|*d@=V%TMx)HdtRBp~L0TA3hE-7cG>*2rr*|~4u z-9E6NSnI~C+=`;Zq1wfZo%e>eUu*r+h5WDd6g=6RkJrSNAO3Kn`sO9vcvW4&XBgh8 zy;~=nbvXr9ax@^6s6ix=e_+eRMW?VOJ4$Z!y!w|v7x{m+H)B(8%u2`@Ywmbstm?s~ z-Lq{RL@2(7Kv3d7#z7hFX2gqiV}pyts5qj=;eSr}H0Lkxs0j)UU`^0vngD+^)dXT< zeE4?}tW=s{!jbo{$?H zwli_#HM!H(n!yX^TM;9*r2tGs!kdQE9qcXa#fx`M=i3yQU+&> zm}j$F64s0bU|o4*=%gW8vDm{p3In$FVlGB+##Gsk@a8hRJkd3% zUu14{3+G<2c0gAV0n$Jou0^vaV0qhErlfE8Z2h*GO5#YmL@)o&a?|zWmXqoRy3`B$ zc_&rgH6NARxt;>VY`w~3V+uT&BhNQ|qP$4^>THKp!hkUERlF{lKNQrXYpf#Sf=bv< zW~x4KqBVPz5CIvSm|uT1)k72bccf!Mp$4Cq3Vs@?Ch3L}g#Pwuhn4S?c^k z#j~HS-t^h>O`j>J0{VpE+AmUpyM4|)cXlRYpt5MZt{m5NqM>A}H9ytD?B@{c9w^Nk zF(A0nPgni~QTG|G&R-qwdhdG}`;?%p z?SRfk8eSNze@SpPcdF>dc+u_D^Wncj(2^DtGgW?buI$!r!9V_+c2qGNbBgiu)ZmVg zZo49}EsZuho&J*tkoh%&u^5)Lq}zuGAU9vkG^UeSB&wluS|1X`d_L-+fJT@lV3h(W0uXs)s4;L@DyAtq;wQTfeYm>(2Oo=gl>#At+!h*}{x4I* zI1zMxi39k8(-Z)kY&iZ0A5H!8n?pZ+tP#>!>WZ7E+ut3+au@e{rk1oEpk8j(`mC#wkW#G)H($Wz!$}`cmV`Dv8 zKULw~WX^)Gk;O3nd5g!I9!}TZNoCA**sWH(^rz|Wh;F!&r88yA7vxIH`ksY1av46{ zvQ*BHhMN~zxKLNL+!z&^$e3bWyE|{c1nVY>M|lZ?s+9wzyq-uV-|lgbJ42I3Bcx{s z*qJB|j0J&;7gIO%SJoRzSe3kDabNSjBMrAYOIMl*1j+aqOj?=(2{lS4R3@c=grJS8 zt4F4n!Ot*U#Q*0*!qz4%u1O z0+9Al*~%->B;}QDBU!s9bB#_Qo^S3<^2VS8GSM!(bTX8umzoY4(55cpiBMgJ^ z1l1o*6q3A3x}l`RUqo@)OqOvjpnxOefWrQd=(i2~kBsW|90zCTEeZtm_Xs{@%~WLK zlh2j!nw7+v!&1C!7U)-5|KO-sYACQZXwaD=k(6$6P6`BUN#YQUI8%pQta3kUJry0u zQplX@XimjcBkmQj6DK*Mu_9>O>%}rpHi93(`$UZ~?j-ux@nrLzS#l|Z%1%H%3Kpa$ z4O~m<=dDBdbQ{4+idLW@I6oGsK@}ngtRWTW!o>sDaQXG4jStSFNvr>&015sTe_J13 z#{cPf+w7f_OFj1urvJ1!9Y|IES4EmyLQ zfMNetgdt1O>WJ7QLe^nNZ+VE)lrbpmY78i+V8aCjrLea|9)$Z8c5JAj@!sq0?|ge> zAG&gcsm#UGgo(^19?IRIWq5cmk1Wfx6rUg5t)SER@Qup5ci4aJf$$T%m(piRo`&~-T^0QGwbo)_!9!LuWhTo091)Az(G@VqMYJ=@uD%T)xx~= zsdDQxc63r=c1za}*4{y)LF~s+&j+(+oKB8!DzrNt88jsf_y$Ekm-~G;})!#e6 z|4o2@uX(`--x@mm(d_B3O&@=2tnS8HddNG6%9-nPA6$F$fBojb59anLE#X66P9xw` z{rpcNgIHn3rJxIA~YIH<58_ic=6 zi#UJRFzZ*35$atme;93(ycAxs>@etPivA7wvu4xDI>}?zVi26h0QRNQQr*CjqFr4@miBh4a=1qU2P zF-y>*r(>#H=(ga9V ze*H8Y$rrhNxr5L}`Vgb-SK4Ta$8^Q@ev|215F+29Qjm1DSBRO_K3*6r)nihz+6%I< z-E70^8&_2sk6r1SS@-zdlx+7zK4jQmogq@wGh+o% zuXWC<(hN^0=|KIhTs+o#vlsooY;j-h+PV6>r#WsJZt47fn$HXuRZn3mGo?ee;`$+7 zlgFY2JiPCZl?lWOsRX}p!%;!c-LUnj@}C5Z|uK8V5UIAe0E*S z-!oMD-`W36_FrraRC&>`E$$#`a)dK5ZtPOv{KE&cr!SPRPUg<_zl83dsbLuFQgN+wr9 zR-(=FvzESn-LArR%>E#X#ga!NkT`{S0Z_$j;3~;9CDBL-|KdNOO~!PX_yov*z{pA3 zzHa|N%^ea7%{q=G-}EkEkQxx^wcmf!_JMN5VcNTjOvpSELP^?5b2~Q^Apo6<+52r64 zPn$iMId`;d?Q+fSv7;Zp_Pzh|S7U$p4sm`I7grH1cXF(gHSipaxUh<;j;y(p<*VII zHwPwu`d;_fSI@k+eEJ)=j(_7u*4%MJL)cZ0!x-P<<<`>WRvKu2vWh;$CCDX#iegA= z42}2u^Jk8zoUW&+5~A|8S0?}D{TKVp)WARvfqK0L@DOe&R!B?-Fxs+F9ob5wzy0JT zaeAP*9e?A(p;uoqSf}a! z(SjuxOK&0AHK8P6-r{IMM4=>D$Ey*Ls#jY(@0~dD&c)j6ZMAnh#K0iv7&i&`7|H$0 zm2Kj#^6Qs!<`1$z>K!_2sZtwi-}dmZE{WC$M~&}^r8r&fp(}sO!I?n;e=L>JDxznK zGOD*#E0;iRT4O|I#Vco^=qxI5Mpz!=bwk;dP6-)h8k-o1R;fQ>>_nK6ss|y~+%~4I z)@EdHq2^=AL2Iq(OcuW2`Yu~q`dXkol2 zC`nop%$ECt(f)cUMiJ61e@AgH9+M3ZeA!O+I= zJWqW*Py9j6_sF}WN8cMe`1-ZBdp#WwdiOrK0zfWbI~Fr)5y?mp(4Zb7WuKW~2$_a| zrQO^A#gfgRDSGlZil6*U{pK&$JoAO>&A+|x`De~$7EbQ1T{)_&7YU!Z{m$O1ypg6d zjbIZkg{dZG-`ue(UV#127_C78)d;q3_M;=XKg&i7X&q9W;@gO>#m~e&%3dDnC|aE; zSiAPZXdM7qZmy>3xxd&`ZVrOxti0)yA}hLW;YuW=(UwN#(;@y=`rv{<#DV|v0L~77>Dym1201U2+50so*mF5U?{`rMaa>y9wR{$BX18j z+1)WPH)zQP0zdEdIeG)vBWl(=-jx_?jHz|M=I6To7y0`W7r=&d0WhK<1try0!MuE7 zy>X2Bg#hEU^I6U?GNa+*_5B`UUJ%2Iz?C`kv_5LdgqAHdR4=#Gt+h4WY}XA68;lA9 zXu=dEUVsof6@nmJ1`USwUiU#xDY6OEJO_hOGxi4`)ZCpo`2LL#{{5dl4T6h-1!4c! zjlabSf50fqp0D$Z)+F&fOCgAZdKlTxhj;xfR_LR^U|*0&;K{q_9~ zH}=(E?=*J+qdv;$lTeg!RdDI;#@)_z?U+80v2-GP>16)$nTp$2>mN>bynFNTdp8?i z9ZFv~r0WXd+{%xET%@-BG7|;Xtl3lb_fuy+ez^3jAHMsq|5P3Pt^fUxj(vTZhWz%a zDl=JhfU=^s3`7bS0l8WO0s?#V!}8TW1E#3?q)3RHczU%ndMmrTh@7r3f9&`;Zj4z z+FoEz?P_Q3^1i0EuC}|!n{FJcS?OrJbC42<5+}+cTZ+{wr?V;qT9tP$Wz8PKAG0q6 z^9*?DT8o}9IucxuJ8XHoKS<_o4z^F${C2LHY%+dSZF;2mS-_MIre1?rV#FlSSZ)=Hb}4F6-tYzPZ2t{hDNz{vMcZN@?=bw*Z!>95(Ss(!pK$-sHV%J$h)#n ztf-f{XbJPMeoxByn8y6My`{?s0sbdHnmYW>_|f+!j=w*7;hT%+zA=0Foe?5hE%z?9 zKJ0F~cM;7Pze^Oy;4nK;U>eNXd^z*U?lk4vjOA8sUs3t3++_YQ`~TI(7e3p%>4i(V zyZWn|Z=K#fSWA}}U~cNJv0tSVO=VL}+QBpkC<=rZ7;o5ZoJWBF8m!EK$kGUaT%@m7 z{gj7Q=wz3eM>m0IWMdVNtQ?wY^v9mQl4+W);lEXP7fP09$V-+l@54BiM9{;>6xx>R zKp%=EdZGwr^w^Jne&WY}oWDG-xC!Aw^nxd=Z=!v2QZ!UupfwNrw%;|`nSZKZMoAjn zM59bXXXjcTI545MXY#^C3m!NSo_7%XhSn1mh@`+OT#uky@&eA%NRnhR;(5hlG4|iu z{~$Oe#2cQ1r;99r2%B3i6&2(}!*75sEGH+<-2`u$lAB}`zUoMoXdZzg3XK^5!o}Ls z<@&0X=E{Zon&qaBy9f5(JIKW4FX%L^w5WIib{LKg6k50c>*p3ZNYXyw`lBW^bqoK-=vM@oT6Fbm;2laawTh+vOI4@04{84Si? zH4|aL=%^(ASog@429qYJvwC&ze)5n1DVL26@wH<*OV<1-`LNP^sx^4ID z{*1XpIg2NXZ(c6HH&A|iAaC`o8TZ>J_iY<*6>qz)XeIj;R%*^#IFh&cO4(XBQB814 z=4flQJx(?ASqhppH`{V2)Qp--<}qrTS$@NOrOAv;+#Hp-gfq_>0TM-dUvrJJ9-zHqbjEa7?!wXB`6DQ5bR)S%_d#;ufpY7R zY9wUU)nvj5K4hhb$Secl1109NY1d$S1UJA#|5P%95ing{Jz5|7I%I_1EjtiKf{8$X z+yTfsn!b}cl6aMs*W1cg_LeR*Yv@qvmUFpqKfMg>z?>$8%(|#!_E!;PtGRKpb7#&v0P+MJ_xsm65WAECxA$B zHuezfKKT4YVsBKLM*Qlk)vKmL)ZMtM#s0aGT^e=Sd2PAu+e;IsH%1cy-aE!Dy{x2v z1ZGl}vDmCbM5i9Ukh8K`U{efZ^n4kH8%mzpb}RjghR5fP-E=b*1jR5yAf}ZY68S3) zv;QuH6BL}Ybz$NLP>D!G7bWOuF#jbfkYqlBI0KMY?l0tH|D#xt;vKX_$FNHoCFwRz z3i21_X*iN+3N_Li5Qsfzqy>g*0n$6JOMkHp&Z5Opp`paWBRjcLFAiXTICE2|VMK*m zy+-cLM~HCjizrg-1C5+9pOcdN>uZzx1ru)u@vJ23)GEbe)%lBUVL7AR^Qm+3`A*5x zEL}NJbL#|h$mx$}`+jh1{P$lQ`pNxMA5EDEKoqX-_GyeDA{B0X+ysDCq6}4GN zRbYyjFXervX7lH(p9TB;X2T}-|MOLwezS3d_!{t;`y2j4AM8u7k8`YZS~6l{~yx^ZG}* zbAxVp)_A*Y*VH7I&{hSu(8d(K=g%Jo8mk`>LZ@DC+^32X>u2G`_}$CJG+-?=yr3ZQ zVhQSh86bN?EmIg!#JnT(OBsOq?784gRBREhTUVQ%ope6zzyA^c165G30|@$?gGUf3 zdL^un6Jeh@Urxaj4{9Ini{X4;fboz0uFuiHteJ|UnVL}enMWL|DxRw@ovW=~ZfRQE z+pM{ALAxJ5x!~Ur(&*|%U;ppo{}2-4o_vesf-)ZVxEXwK)bzQdSAO#9g>PQhJslN< z#Q57FYNm{T^Nsx-cMk2neMkUbG~199&~$YKz{-CMO%+Rx)nJFkj^>rFx}{E1^MXK_ zaP6(G`s-c$@18vI+W8|7P8_&B#Q6BQT=fbDfd}aFB46%TQc~|I>x@p9x8+ic4amYi=Gm@c8Vx zcdwp(ySwwzaSW><9L^XbALHpGbBReSi5DA7Qi*9z2jK!3t3b)3R#?eMDq9Cz2_=AVpUO&Yk&Y8i{JVH`p((u2?*m^oXLwV*

z!i0&GJkvZShV>L6X#c}GA}gjIq{Gy66I;ha_Qb~F5xfk`l+q4Iz|Covg#QP8#K_N@ zqgoV|?x|{D{q$Ijn?d_mafp8QnJWBM%v;nHGA5f<{Ivn1i4G94k3J5a)LB}PQo**B zDX{4Z*^Y#LdTjmI!BFa~D_XHHea^?FXog6mugBA)lGU7C`&^qny z#mgO@lzSL1AZ0K_HC^irY5Q!8o&qhv&37-J{`&O55ATlu^o_pn->zCYwP(0lWGh(G z5sVj#amNH%`H}hd=W7)=x)Fshf3@MO&CmW;$o3$ICJDu@z zcVYGFk@DGtNHXX^xrUQYv{g=bR7|y(PPP?}w-k=H7zeKlfHyJ!UBpgeV#n2DJ!Q{d z&Jh2DAk=g=UCs^t%$_W`y4FRS61)1UxAvAw4FE4&N8E%5jjzAO1+={Vam9msWj7b{ z<}Zp=WjcawExHL*h{jJuqIUO4$L{IFUK5P3^DnoCu;O z+d{-ij){b$8C=1kVDrIX|KDdz|T{1 zWWkKl>Otuda0)i$J}iGI&nVi8L&)Np9kA3W$43mVzSVAyK>jQ#12gil%5f}!8;vh&Wd{kM-Det41yL-$A520xh?`qpsIdsjxjG5Fw5?l1rB#-;ar&%Jf!^lKNX z^zbQSX{1xr7!6N}xSDDZvda3%cva>EnPFG;$Qbw{_|IHClecsscj;W#!f76X@II

23-EI-o<1HtQ-Xv8sHuX#Uy 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∾hnz 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

!1A?(Gm&Zq ziW36u`tYGddgzEtF->LSmW5IC`e!zcj67gJ{rymTyHb$_*=jo0uN`Tad8t>^l(vW(ut4_EWJTQ zoQ+0*$Q%ZESu4Ygm^v6M;|WqM8~3bbm?U%8_t z*pAm~#EzD+3vD6*`^o+9DiH9vB+rZbs*Zq?utK$`B`5&Mi}HULFT`u*;WLV$vO zZu#e8{O36;(ka|lx4h{mE=em}csoh}b;$cJicpIqBiAE`^M5({-Lb1l{yBIR6cAD1 z?g(k1FdDqP!hPKlthpoLg4iO*b{Ox@1a{Hl!c7+#E$Ffqj39hgHhW;`#}a35*R(So z?6I`P1A~Yq&F-r^A~r+*7>hS_q^)QTAT%(dh4hQ8o)I1xa{9K&?BPr}fKy0LN&x

;J1*OTsx-k-)4ZXhn-m*>Jt21(QXJFHV#`hOK9C&sJ=?g;y425m$5ktAg#|>3v zgM)f6O9cF9oGBY;o{lHXPyXS#YyW)j*>wkdkR7(cxI3vx(T4boPjB04pK@`g_p~o z7kfHgKNOzeaQ&(JLzj*mx_q>Bz6RYRFI0geZ8ER;WF=HQdLDH67$&2T@40Ghx!B5l z8ENyO3x^M#JHT3&%%L1;lOSt^SAU3)DU7ZqJ&4#5jAi0LergJ|^wc9#Tv%fW3gof% z_Z~WM=19e4ZQdk4W+g0~)sGbv9jorR+U&lY1HL;jDcopcf{vGCzY zSSctFkycI@)XZ1zKEJnkrVI-sAUAC^4eL>YCZ2MpZw=VKVX}Y2VtUHb@@O}!qY#z{ z52geRCVSfweTUNmM$)mn=d_Fxx8GwgmjsL?AaO((fB$Qbo_prpq0@USrgL`BmRDUk zD5edj6vXPxUb&kyyax+{M~edna{*!O6d>+!OQy9-+ZR-%(&XEw0WBd|>^N94P|^3y zX!g)9M7cF*_cIa#n}^T{IS|=6ol`l;5?CfazS05I!K$G=<0T1hb& zG{(|$Md$A|oZ@dyfm%U|LlS~~R0>|Ah9y?mn|>1e5O^4NsqZufP~1@fGQ>gr!s~|R zGLm&0=+y>n>kZu6>j!Tmisg=Axc%%C<%v@T0owR56VoJ4Y+n@#eQykPjeD<-HZcj( z#!f$~kI>Ql(7{q4Q?{oim1;;t``tksjJ_LT^MCtz8KzO+@%i+{(N3Yd)X2 zR!ugMCrbwtoOH54i?LBbpGts*nO9OtE%BD<0Pg)Oo~tIThSd%#$-&q-XmbVB3Y=B2 zP>(1O=5e_mqLO~qml9WhDbc}G@f_X@sFwl+$dy7s$^qb)i)&S}9wEA&q?H+9nTr0mDfh*cs z_mje0@W$>e0>LWn2`I#1hiC*q!a!Fd{^y|2%RxAhD1g}l3-7dc0M!A9S5F8P>&6aW zT35`lP$1yt`@|bh|K+2<_I}I8vRBT))bQpmzrxcsm;d|0C;$5GU8gH`rijqqD46pI zyxnkPHYd{rBvr$D3swgQPCy$1pE)&TNV!vGlixj2F}*v+oQ%j5R)62EX7PBmCZpnJ zunYMLEnuDyyeWZm(nQmLVr)ulZ z?A=c}aH=+UvIt!b=`K=I-X(pqfHb&bzHaZi!%*lg=Ne!B(@Vcz`0vuWDoi1eA+i=*D&F|Xm=6r5V_3xY!?M}Dw(BiJ zPmkmLvzrexhuuvk0(;nUnz>oC1$!PiT6OJ^eyR}oMPP~dJ_1WmTN2}_%v%NYk?aX) zo@z@+Uqs_z{@JNF7JfbU_!NSoo`?JG&)Bo3%A}WSkJk-K=)ol^X$tjza`+gvKo;aM z;z?NaKwD<$SXTM`-sgYwqrWZu^U_Z)9zM6b;oKos<%$G%D2s`wou>F51Ig@C0sjN- zS)}3-ghlL9P4S2x364-VR0_~pCG!<@8KiMzk@bsAt1&~3LY3hTnlF?LQ1ndZGSABg z+13-e73ZAZSnLjbY}p*>i10&`O)djrL;;p6G6oXHPv4eK`H6$NuZ4XC5(@|oNOWjP zP(eWc(8kRCk(=n6T#VxD{WE(VTy@B6tFHykRr3HA^A%Q^4nH|q}lIK!)sQX&I020b+7xib=KV9&<82_>TRQL~o z^E3x_qsGMKoU1q#{`00>s!;JUpBT$kr*+}KTqNkN;t^-yqdB=I-d7#G!wyJV10n>HC_o56@FVVUM1eM6!TGkpH65YC{G$$P&sk%LU)~{2fz{3agp6hF z;{M041RYooem{^delPve4G;B@)x&|4*CF{3uV9eGmdemQ*T%+4 z=oc~n9LA1PR=&aoX><_HL`YzKBlRT7lmJ39(6q(&VZ5+>y0r9IX~9H6CfjLQT&S4{ zAy}1}Xw)Oad90?|b7g=1c-0GUKY#Y+OO02LM3|#dm7~DPnkixrOUr!oci(v7w;%oH z<-dME!2wi0y!68;QIq&zq7OX+I2MQ(mRR`=XR)ae28P8e-X;uGQ)p+`Up;~<21+V< zGBtHPrF^pZ==A>Yyz|W96E>tiOi$}AxNfHTVZ7NFnQBhMUIU&jcO;K4K7HG(XsbPKl1E?@*qHHE~;iH2qL_JbZ@pai<{z4;q3) zOW||zLzKxWvvh~S|034PpQy{6%%LJ+id_6TEn=z7CI#juq`AWaICkUO^U=MqX&s_w z>j1YA9yUE6lX3uUCv9BX4RjXV5tsHxr%dMOP8aXHb~NuqCGB8nBAydGoE>1NFiGIk zp$PIuSKpmre0I3)RxfkYO^@~KteIFSdkI);&W@2$?FJ-C!#y-J(zZMy>iZX@BHWRu+C8T_RB+e)(OROkE+rAf7XM{?|Jy1PD}WZBW3UJCc4g zEw!j~>Ow^T)&cmAE-mUBWc-q%1O7@!sz6@V9qJvq2L8$6`Y-Z-jiHiYp^iJQP4PvN z`MUsFyBGv;5t>vAUa5VaTr|4+kyXbS`GH)cG1Tq#5gX4K&CN8 z>X~v{Ctsur8J@S?Qd6*sQnEg zOaVjnV+6tSFNjS!v|(W!+9BcT3lku`ngaRjz`hth|EKT0()GYV%CS=5-M!t<*BAzp z9Dn%&DmXY^@qg%#3}7z4Rd#_f3$VV!oy{_o5B$BO$75tkKaho88(Y^w?AZRapT7Nr zZ~gvd2Jj)PSrfMFTy6e*1uICH(`WVvZ4d2Z)b(xyA)bA~P(YD==Rlt z48zD{8HevXGW2*a+jvuF^T-~_TAB7G-=?+7V&9UJr6tGnYv+pD1-WY?J!QP8;6&Mx z2ilHY>pK3_#G^mGpFB1iEw?!Z`iQy!{eSgbamh&5-s3FcDrvZ|ui?JKl_zU(mf(6| zw5VC)MhbFfvxz2qPgHi_G9-?pGRj~;tZ<^}TfcpB{?W;!=MEgc)^OzfK7t6yoI8=0 zJS+}%kQ@HCWPHY0xdqmN(z@YX%mgwgDh}P-%wCo9)AbZb;>o79JlI?hXxGhGR?d_| z-|-cZfs@|T-xu?r!PK&o)%_25CyJ|2))4qm zrNRr5!?TbjuqTBG#TUXXZQyWW&|o2`xY-i6xfe%q9Z{IXK4G>v*e<(NuxO*8;0`4Q z)C#s~2d=jry41A)T66iOy_9uq^GTnm7`QqfGMwo%lEH>wL^z(d4Bwu_^tp<(sUo(# zk+=KNtu}+hG`ajX_4>lk!zN+uDIUuveaV>`$b5+fy=-9dr!?5o?X#mVi0%OTPbz{f zMnAW{ASrVuiqLA(FQ&PS$ukVU|6pd+WDPqXJxuzoeRPdOw)FZCm0~99u!E+k+1?Z5 zCOV&do)bJ=$aq)iXc?ov{+6tr-7%^Wz%=nXgFndcV*5dU4!XS@(Ec0_{0-VLnXQ{ z>{6rzx9Wenb!FxXwZKE#uL6czU9cEq6&`|qu7i_v26>Lg%n%(=@+*u5W&uV8hKkZx zx2pS~_5y>79FBg3)|CJ@Ie2&R6m{aiy5sl=&VZ#pi0e~u=l_fU8l)@y=T`d^QZfkm z%iC$!5UX9P`YbB#S6`j>VbukwYja(m`V#mC9EY>J;d-)su2?F9RbPq6ZDaXe@yqVc zS--N@i-dnuLxg*KymwbD<~iG2L-7S7rAH3Leb`BILnSoGRcs{03$YeAmaO{}8#ZRWN4vdZ} zH3IAeQ*6*m;6HB)`+;!u!11~ZKf3zt8_&GI@R!|FyOFI1_lIGLA8F^?K<28)*rEDt z4H}{9+0s}ut!H+Gk>uCznXWzg+zdzyM^t>Kh8940e@ymNHZ~Mhr%H=w@=Irn#GLtb z73WF2$Xc7jnxf^1$x zSCc{=fj3d+R3U5?E+5EpP+0M^jvdLUIJ>+1k?tdxj@Z9pntyQ$KkDJ{Pwc(k$dls^>u|<4OZ>LJFqT+htqC-&f6f3lZ3-hVWY5CHyTr-M|Ikq{)oxM=EZX|VKR zgDFU`a9~5&N#7g^4dJ8tvEJ;7VreL2WQy&ZEir4R;>GuVhA9vme%av;f8{llM&kgb z4P^+w+x%A3BL?9~=C}7TSLKP38agFbz|e0cD4>6adqMobuP!bPXo1M>dFGZL9f{D+ z?qEs-m>I;Pk&_iZy(zLRqc1}GWnKOOgV~Jk`dM-bB@q7b`Ml50)H3&Yd-%1{%Wx=tzM))O6^IR z5BRh1-ruNa1}9;I&3L zEui|*;xZ&v!0q?_B>pR0igC98LI-AZWFK7!g=c~{I*nGs7}yRzPGOGCK$g0@Eb zcIi2`wCb>XB?>SUhC9%*MxUh(o*2X}Yj$7Sv~yX@P7#I){`)L#_FmHDDShGA+e0E` z6#Qxt0%XAiuH)VE>y2@Q>rjj2L>I@9mr>?|nHeNiBWFJO+=ag_eE9PZeu480T4Dg7 zZW^5Ds$P#(eQs+FJ~XhXOgFcAy0!Tt5MA5miI)4>w_bkxqrbnp@a7XAJb(6=58&AX zjE8hb;MgFF$D!B@GywMztI<*8?&!`Tb zNX(yt7!iI$7Fy>1cu_ zH=;j2dO-N7f|1hL(%<_M3*6-g)Wl59gb&H?vDO zd?*z>3>i#kbd-(fB`5dNp5Uvdm(hExzvo6z+k>5iHk5}5Yw0OaU&y3`JsBs5Li|OK zu_Qf}$POz`XO>PVFv}SjBG^4&O|zi&%HfJxv3G-r6W=piY@AJ;^GTci#xu4eS+vHG zNoJfWs=a&^lMrE|NEocqsG)LaOJqjuSQ+0Z?mdYA>DamrC%eJ_pRV6`b`RziLH1bc zM9+bgt+phr^_eKw4Pv<#L+9Gxp5tXsA=9QnU||8jbu^FoWupoJ_9^R75CQUB5*jCL za%(OfL3K~(C3P~J39o2tEE56dZ%h&kAoi(`P}I{C_p+w3l9-F38%5xQ|A#xG#N%L7 z4EaAjU%#Q~9j4GtJ)-k;Ge^;k(2HOxlXyX20D2!}Ci$1B#}eM2C_h^^slHEtCcbkt zf2kw*t)qU41nO=1V&hK_w<829DS)j&<9on=*g3J48_bIwt;F^ra-=4H@<8;&o4NyCB0YL9?ACGy;bJVEf4aDYwQ;&Q0D*A@D*c!nfwL+=^Y34CB>NY5+^ER zCd&iho!Vkh1+1#_ro*W1^U{*}Xkny5CkIw*5ClL0kCKo(S$#ol?VkeF8vZZN&lM(r z0_7BxIWg1qUoL>vLI4zyL+~lFMxB;?-ih$safyW#v})uJ$bTpJtJk`))OCl)70$cj zj`|?{(}n+wpUm_5)Eurvok!Gh$J5jaU6De4EdugHCESx({*@@bX;%p2>*7$glIv95 zah>0BM^z9iXljNPUrJlIW{($g(9O-!jA{EDlTaNn2;j>9#T|||P^*t*{>^TyS^`-R zCU!ub(QE1dwgpoHfd8@y6#Hm2W7?7k85U?~VVn^Aq&i3xG)~2S8u(( z!1C0Ek3U-Y_`{Dr`0a;(`tHK3H{N|>?0e&I@5Gm|;aEDneUDh)S@=ixOc4f&=#emy z1L|cQ*v{X66!|}jO}1<^AB0i`mKc#F`&pCgTL(vCRQjerfXR}`R%r_?gvGB)d{_yPJ zW5Yc+`wyKsR5DSAV`Sxg751Bq^d32TaQvy^+3!xVB`~BXGSnOuHJX%UPiFQif3}3S zvVM$_QgJ0>#?7ZU1oa~qO!T1);S+J$2px;&N*W$$=>KNl-iv$7XDX{sRCHc%uROjB zdLQzH{X0pcX{aTqA0PeQKi)e1{PdyIM-QJmcwoLJbEm5Uu5dMd&YU4GbUqMOuu zh>oU<>rT~IV1IY4xMr@b@>~@UGRCE8)MMSviFo+6w zLE}UZu!~t-8gN&j1wc<3mwu+JSa23Uo{=(@Cu``<>G)F>&(s}#tcNxP8!pHn$Qf8n zxf4NtZy2j*8g6t!E#{x8raHj?VG9*57s&>J(JX{X!6OBML&g4s`D`dgFSN1S4+Ux1 zXhpKi!FJcZ0|6Zl-SIDnO z9@niy=Xo3dWePx;|8_49z#qXU_`klzZ$m3aE5Y8~)M8mlla;BHbrD0mHg-jz3Rqd? z`RVYbpGE2)x%{)C_kj5zDzO0CS%K1Gp#Hb{zmy3YPy=PI5TL+K(9hYiRp)Wts$5;c z9l)z#6DU>(|6Gj!>TE9L=k4Srys1J(EwZSqRVP%)>3T%nQ4gxust@9NJFuEh;W+2N zo=t(jlb@0IUGy9|t+R@e%ho;ucclHXD1Nz+-&F!QJ{02*pFA6v!E3ed$ua^lm-=7P ztG^JXHLSyB9FI227gATO-tV=pQMauv4k2hjkKUs-ijiJIfHo1pf-n&UK?<#E_F35& z4FA8bJ$7TKeq&bxfnare2wNl71_4zI5Cudtpv{Ysv1@t*fqhj1knnHs3c+lgg~Ig3 zM48qeL3G$;@MRYalIi`YkNoD{-~IaIx6)_wDHb+0pi*#O)#SdtAz)jxAIfToi0{1h zLy-UD4?p~XO!^}U0vJcUxA4K=7ZzUo@DESE`+}O*59y5v>y4$!`~2HKgoFoJz<)S- z=wik;Nj^zU!BXfBwi1_I*quC?4Oz`=i3_kjq~#zXSt5KpmOFUG1a-!y4i*-%QE|Mo z?)aX4^Y!yD&kjB_#DYSa&R~LAz>TCAjmz?P=z4s^Sb#+WkD&zPsJn)WizoBU-yFF7 z+BwTp!+p29%TMfPYznh_N&{RVYERWbu)MeM?&+6i7-T?7pa|9%X8b z&I0{G;nnRiK7hZO$?I?`9qJv1d{KDvapKHLzSUQ{^(`q7;P~@U7QtCzA5k}7ab&K7yxsJ8 zfA_;Zo!7gYu66FczX^pEQh5j&#u+F>7%QLvfqT!JD4=1QGLeN43)f}bGx$m&@44m}0@?++(|FYS3|Jzc7s+Z!&-UJQ%qs- zoq+AM_}Rd&nJ@@nM-Gp=2CfEOD??H=7ib|dkAP(~Jx!0{RK%8S+NJl6RJi;^r8cY) z%b9%!GVrRB=8ioR&MMfJL~k0R9>+omPg*DFIa|Nk+y9-Bu@`1q9~sCyU5^!~+dvqa z2bO3sjYYwWnM3P?-BaH`o_D+)ktY$scQ7_+P&_}ypTVT}v1bIa>*qubvNXsdrtjgw zAb)ft)ksw#i)aT>Sug|*{zr~hv(??l#BzZg*nR|}aywGQGiji#>jL~`b*~Hj(fp`` z5U?2hCI8n_IMw#0#8wSom>;D6nEbE@3Z^TaNZWaEkm%EUE@f}{v zd-109WK{@Iw<_OO_{norr`7Rf7h$g5QP|7HD7@t*u7l^h4%dV7UMip0fLeMD8l|tI zn0iNbh3d8Ph=acpJXcRx9Czd!a8g)+KlO|H2=bsaQpi^d&TA}?+*cinf4MyM0TuGQ zz76d4KC7DMT8o7K$d^JH%~;OX;I#*R)*SU`91LqX-;UUw?cv)yWJkdI=HNBWL93er zIaW0WFc%^Qn{vh+hMv{NDZ9)Mt_J#7FY8Q_n zDU%0e86W?Jtd8g)vtYdeE4tl~;$)a}+i!H2p4sokKqVbsJZV`fWboSF<$L<4mw&tP zzyDlVc>lu>!TygIfPBIK58r2W?BiG7`01q|JWzFRAE@Xv7|uX3^IuTGG1e@^Ht5wM zWY`gdScv?eycGOL{{vVZyxeU1_Gr%RE_fAqdr=SCV|bzL+QwlF_Z73ANnu)(IDN5H zrT)Uc^4YSI@q+#5_t4cXI$ptlQE|lE^rXSLlR1@h#egS@cgQG^3Sya&1fm0L=vf?7 zJXAnK_VC4h`{oa_^YO^V1C5s&4xT+)aklc@E2lqL_^|hCO98vLhBIiF^F={=7tZAG znXAh@#^7)wZ3~@^4OX&Q08KkxX<3q@?HYi&QciIcHS{lVhi0mm=_fWF^aAccx%xp4Pmy_F|QXuKE1o`R~r0 z|MAJg=k}JIC}%x7KNPM3{Ku&bGdK3~;GPj=PiE5D*DM7E0+oWf0_3TL05SQoCn4^_ zx;em_MCiwP8^Qgz>)}~LRg{Yy3H6u8#;TYI&(CSxJkkf+rPt{ zdf;Z8bPBAQoJ1yeC$iRe>&W4^_5{dpa+g1ThBOgaB36BVf7yloJG-N3I>6yGrAx+6 z7m0RQ&P;jvxxH+E4xzzq*7G`4AKhc^fxa(>O;O^4sRZ+}uKW+um~lBeq;$4YPt^0Ou5Ex-cDFGh+O zUWxq4`H{OL_)!2Qp3ezu6ly7Ga-_|g+7sO4K$Zhq5+gW(eOH#N7#seJ7rM|}A?h8s zfTRSSMa;PiKY2U(FAa6M!#{y;{@0ba1Kon&PRa<#l`C|j?&3GPeG(`B%XyqqeC{i_ zRW5mE2xitKDd?B2K z4@+IfY@Mt*0QN)f;cG`sC2yLteBFM(bw}CW5{o+oa{(MX+M`($u)bNR@Si|HF^CLU z6Z`}~{*e50t4#sR2msAresfe5;FkL`5!ofH<>+%U{7ZL?7BERT%O8ar?Fko$2W>c! z^k#h*`$qjXc6x6!v1=w2tfsq4dkZgUre+w)3G9qK^^40-z5BhNE&R_P7ybt4L*D=6 zw_k0z+0A6l>Tdtl#vo?cw+(o*O53eBn4;d-9>#uir0mt_>S1FTJB9raZNIFl#I`gd zYAC7TR4Jne&;0L;Sh|TRkVyu7Fadx`fcoBbvX;RvRp4qHyV8gOQS z`bO%5Oca!cu7Ns+41wGx?N`1NVn<`m2rz~R3`HY7A}#>PdBe$K@;1r(_~NoN)qBqE zKXjr2zNP27@#BT}doMNbo-f5MAL(YqfGjJFut&29jFi6QR3*EH*=a&e0p`n?m?Z}5 z8_}i?%6>8Vr#3rA%NzO&&YWH?V*(9V552MQo8q}VUK?o92iT%y*VRyb@>Ev!nc98l zkAx11z?J4H`v_>@;z|nrMF4_(XVMB#g}aED&P5?lzK2L2Lwn3Fz*S7MefvYP?4usR z1W9NpyJ-8_V2Po)5$XmmMOYfydy*JDnoAT2u$I5@yO-Yl$D1E5 zyu0f}1$lem5F9>=FYqv}=2UIlwHB=Bx^HysK3>i=0hAg7d-?)s+OaigdA#%B<^8D> zxv=`kK1tD;d*V%bFlQtOqKVFq_=F5FZjg*SB`G>_pWv>|{Kg~cWTuQYE`Tr}4YPVN zY9PVx_Jfe86`ng^A%-FFJf>7=rR{?_{-vQ%Wr~4v$$KzsyCr5zziwl106SB-<-ivO zsAoE??#iKor|qpznPH!#;oBRCH3WfxVXp0lU}2vIlA}jUF=}S5JoPf2m+a%Ec+}x_|g$zUKstS$o~5x2#aev zsm*R;;e-lmKm8$_Ri}k zE0bnxp#66mNO{&e5$p>+D zjsG3~JFZ{5atSLM;RB+&cE`Bj+VzQCSGXAe1++Erhmb)6q^{ft;0L6EeMA|yr9Y1=)*?vN7@bTA5J;UkQagnX$lzG6c)IqCx8l+EsZN2bDBiIQPQ~&;IVE$KQOq6=Byfn7&XYUjMH{-k`Lhi)u(mHA z+x*dIk6nEIDz>6&2Y}^(!G>ghcj5iF7XFwsQsg_JW6BufBGep- zL-NDFed_9KH;12_?0L#s00Y3nKC*F)6fCmR3$zDS!~{$>nqd?Wg_wuO1Mrcy#L^Cc zbRyQ^a?cZpDbOIngF2FSfEpJaCdHWN6<@LuW)Kq6twNipPo-L~8HOJ=9XVBV=)^(e z_0HYrc0=_C4Cx>-a))#FT-ej}a4XP_O$0;1AU6Iv!g7%14xwC?6~hvtAY=wb#}Y9b zyXV}V+WFd{hYWB1<@b~on50EuH)LgsO5D%VYzf(eS#*t)Mv@pVBgUbOrL}>tMaQkK zvNJW<(fitCpe)eLV7UynPLhn)g(X}p{KCkBx&{Ku!xDy!*1bR2(}bUP6kD!PyzotO z@thL{X7`f=%~#rc9_z0<3;yf*CL!k~1MiR2k0zGPmF+nx+96^YvRFa@YzFXxcBpVN zmo@ZRQ@d(st2=MBvWy{el1Ni@5LKaW#7tu_drQ9_V!Zm&zSf(qxnkX{ z2j^9v9rFtJp4ceXAEW#+C9!f>27#^A8p-qp_%9~iP|oAMhWr4d2Cy1uS{YS<78^`v z`j{mw>r63TZQ=el1Ow^V1i207Xwy|X(tZ$ry)giF<>tN+;b*!-na-Phdb;P9W%qrJ z`eV5a^U}9nk6i;+pZ(}C{Q?IwW5%n!O_@w0Z0UzDmAT{Ob* z`Ufk6hbkBWpp>9kma@7pg6X`-iE2Mf{(3excKNR93c}Jy5`H`!T75Z|wu!c1$@>-T zyTD&jwd83M0{#X6h4ydpW5Nq^3@KDN7AWJTNz>Jtb9)mf%2^QOJ(z-w9Hs4D<%E9qfcAuyKLE5c`VySd`W(eB*J2lj>H*0^)_l0*&9`X^z)AJDV!+ zrSy>MLxWHk;&Es3;etWOgPIOs7@L202#e)R3kz+2#`XFSII%NeueE7HCtB`8%_%k`)? zQtz$;hl*UEA$G7mfw?gFy2yLJoVJD^C~MlbHYMQ>f!PAR0E)hKts!fgLe@40uWayN z$-c;DcY47~TI4_uw7iAGu|b&MC3Vm;mU2LhL#Y~Miv<0nZCyd|KU4u&`e56I3n&v_ z9Ee556v7xqM}YfO?xHd13+!NY;#0_h-a zT%A4UhwuEv^oX5=5PZW0I${)#C9dhZ;WrEK{F5rGlr-#@FvY-89j@D3uj99pFME@YnO5$d4|&=x@mJz zAjs-Tn@m7Z&QQw`O32>XiVpo!$xOld{TK?Nt7N5eyfrt`hM{z6>0CWi3Fu216Junc z=|&@(PttqXczhK+ShFRcG!AHGmWuwYG+WL3lG$?0H%v#*9%Kh)!E_nvwAdpsOkvfd z{N$Fk^6bRH!HF+KJkxN6HN`?NK=mBHdbsvPRV6zvXG?1?>}CW2NT&eVVPdj1inb2D z)NuB{SoAm#07_6Ie2ShYd-@*f!LknqPqs9&vCEc@Jf8R!HNoaJ#)MOR#1c6dQINMe z&AmSn;vINLLbG{545^SA?C1#~NMYU9vAMP`KbIS7UvBrmcX&i{izn|ama407K;neW4%5A;j zD1V@Ip!BH@_y}Ao98Sn+zK4u)rTAHMLPtx8Zm9j?{Gn9|Iz$cVATN97DnsDXPS53C zzDtqu8{C!{yq0u$+|%wZu#b%!_}}iiM3FqsRG$DLF+vpuo$gE9+$0=e1k~z*%@=;W z;Q#hE9mYO^81RndC5}~R9NPo)6F*V5zArL#BzI%2FG|Ayid%CRmi`F!6IOte>TsdA zLVlPZMFfF_0$;AAlssHZp%*`>z=~TZ=t*v@4)tVi9cNJT_=we?7>RYB+<6}92sjSy zzZ~zSF)af1P9P;Kmis)yfAJP@BOts+I;oGNV!`cOr`S?~|KeM9oeGN8|62_~o2LeH)I8cV4rqSp@&J%U1X=u&=cSROr-RD*^`af&7F6UL`&H z=%t^D`ug3O>sHtKu5St0(W+-a*ta{@r!#IRRY03`0oF8VB|wXiJS(`>4j1Ro9Udo_ z-~jw72j~vK5fK7V@+hl7`oGc$FhU0fG1!i=A>0mCfZ%_3B%M1BtmNqWky&wzUnskz z*LVA^H~26qxwgv#%-_J&Byv!rKkCr+ZC*PK;y#BwLxhW(>ydc>E8uCe$=9q853S)jR$m$jG48_on00Mdz^SsD|)(WxVG@In>S#U1xIl~0!!jTSLo zYkSVZWLca!j=d_v?GL6gYfRpY`!qxoP3PK~^5)ZryRLOL-{01LtG(q$GvmYj7q-lF za)ImI;oP?Sn%Ig?sRI7fmIeO-f5;+A2|@s!3)T(Dn&Xk|;_;%s2im6|w{+dxvS)s8 z_3`?$nJV<3jW-QQR`y?O!pIsuD$0M%9Li5uaXl!V#FpR84^anS1U~!P63Mseu40Km z0BX2$`O%1knFoz=6wdqk{Vxb&6l*L{Zta8MgXeb|fKeBJ-{M1R$>uK zLPl~>)G*P2=L1xsM^6ayOJq41%J~jv;V*=kpMEg~g@-vFz0J0PIPuTv(Qz4kgutOR zFMBdJ6vE-7(&-6Av5#p3QwgvxfIRjK%ph>UM|oRgHyQAG2*#F^ES;j2>DZrkG$pe9mp<}px zZ*vAaT>J)eH}yo5fvU$7qc`|)q8zjk6W5B{9nM&AxQ>{ zK8gP#N_1rYngI@&Be}5?pYOQi$bK~hcF^gImISa zSk?|lVlOXQ#OHq@=Ju*Gp0AxpW3IHaMI11c50VrAc{x!-fZZvMw;a6s{kS6 zVA?7%M#H#_&qaKlVLj#oRv-3W->7rzN@Q!W4>oa~ao9x2(ud~2bu9twTLZC%;J_3D z=0~EyqRuaJP(+~+kD68#WFayFI5JB_;s9U#@kOVQ=`w#Hs3Jf zOOSJNSIP0xx)b}~UHIpJfAr4f-#u>o&dkZ5U3ulhU;K69?`(~K{14A!_z9B_*Ns*j zcOZBV;F<|j)~E8mkQF$RB^@g$pDoX%X7BUc-0R7%Rj8_+;usLTrC+ywK*#(S*2-`= zjG)p=0Q_;q!8L+~0!+8jGN5Y=u@i2OgNH$CNSG4^2!_4A!HOqwhXcXExG$JcqOGA6 zF%KmM96nl2R=_mfXgYNHP~BV&j-w6NnoH)3@r95ct1JsBD4DISIkN}f8$3LX_jUg4 zgI8bp-|tU8Gt>K^vHQVxh6wUbl`?7#Nky^^6HSv!})`CCu%T=W_*~2h!W3h<`{|e zsnaL(pmabv8q<6b*>7%%3m8hltJ9yxE4C7&>AR+j>W-JxpQ*v~87DpEv@c)RU@p4T zyi?VXIS?A#&0>0dIrT5wsu+8Y_XN_gR8Rs_=cz|7I zY5T(kb&(}NE7>x5+?y!|?ZEhGyD4%b9?P^`QQcEx_8`a!AOi>aIU$+>N|Hzh?oQX~ z`o%^s&=x}-3X*R(g~*e;Jhx+YX!PgTm9B?KI{Skl@aY#bv<0`ro09nxO626-0Uk6m zOwdi)ZoP@yx}zBfkbm0qSeoEv!la0qxPsu}vcRz-L{qr0fd9)i4~Kgg&uR061;S{0 zOK&)wD&v`A@_@GwY`-S^ktpD-)3s_{OW1fsMt!{z{PUNN55Sgo_9iD`?2|lMlRQxy zKUT^0tm_KXP2{fM9e}0$7h;!wEzv>j1O8u05YpZ`PAkn^$@w*<3bcdug9bF)glZQ*8zQ$@$guT_)S&}>{Y_=3IW=5n2ZMVdx${+yIpS`~D z#-C6MeT-IU;h!IW^z5I$hc*VphMo4Z%7zyZ1NX?{`5H!w(CV`qlKh{PxL~{-e;#&t z#f_!&w@izfw`S1*YCV=hlEXvY(CvlC013%UagdOMIkG;Wi8iQS+wjgZvhYw#L?E0G zhW`UnI1oE9{De_=v$4b^m`((on43xGZVeVmza>1v76X${ca@cnRi|qXT{*n>-UAi$ ztX~nUe5PMZXUcY;-a}V(&zb$Z#tRHrI)41#k01W^6N8VBPCPYw?76X~i$@d3(xg+Y znSat9z;T)(Vw_Y-)CmD-U%`Jm2q=7*;X>-eRNK8ZfSVa6!n*fZ32!j8IU&LyoCvj+3Io{V74zQWsU+Z7%&tRbqu^dRw)eA8KomhcjGUicEvcTCw4MD)nyHRBu*p=fwrp{eV08#v z%;<@uF~hPIbr1yw1|1Q`L}umkPFJBUr5ym1v#~dHeXrE806QfEMF%rz;y%<9z!O-= z$n-9C2egkY|KczPGJS@0Q#V!w{v(0{|0x85h6|wQn}NT2J^F|-F-!u z4<2qyI(Blqx+`@1K+M*@s11e?SW}hNgZX0NuJV7G@N)3906qsckJ_BCmic#xx966& z5O)KiJTvuJO~PDF!f<&Q-ac)?p(hIP_7TL0S|)&xSwZ~rFD9+QXN+W0qw5{xvT2$#BB%1!ZpZcI8{cjYoi3Iw#a9oKNp14%?Uh0P;x15>5F+4)K zuf2qzDNAIcWr^gfnyqV(__=kaZEcGu{}1fcZ*AAH<&$GGrE9xxV|y^aHsHSt{GouD z0$AGYg*(L3Hn9^V9LOWB?lL&6{RZMUzQGubG)Q&IhyudfcLt*orJQGQ5;BJ>fOabS znN*Am=4(3d??3sId(Zs(YRQ>;7ALV{j9}!^7075$>8Tnzv#{BKIR-&^VWIp1-;Q4G zy!86bH$M8^`{*e@mLV}@q6`iEW8tGSFJC4HMw*B~g;ZQJ;gRGQfB!N8;_ZL_`NnIH zu(lg~V-I+;EfMdsU1JqEZPuKxFF#wuGWY7aefSAL`;gw#MCRb#(aAs%5lRr5XhQ@T z`;)24908q2cXKH1QM@0?Z0UG{46xAXz;{}MeR_1dK2`vPd0TawVNQY%LC_S+ieyAJ zbd!N-_!-P+=7ZToCm5WYFPG_2(bq84~g}VCKF9b9!$x_gp)-uGx+u&?taA3a-)S|tD5tBYR_WM zwuj80A!6kH1PjrKT9XKrsAK_u0v}gM(>8e`gMPF&RUuUX+FFG4%*>Lm6BlSqvyz5} z1%-eN*wVQk)<+M?z#0@B!b>Km*>Q<=2E{_uLDd;m89Lr7LSI9z`DSTQrCE$Q z5`-RoE0!8a$ut!)Q1Z|aC#7HA3Ha++2Sb&?`+8flclIWT7PQ9~8b8RM z$CMUvfky}{R2jr6aS9sDWe+=x8XM6%%b5-hu>LU5nyb<4t>kHwN$_I2-3cRE9xE*)6PI-vDdo30ZquP^4glLi+HG=LQ_n8Q5f2i-~n@_*`w>RHk_}~v8 z{i*i&VH7*qjRp;inK1JLxEX^{2qV$YFh9!{V8R48adZ+90m_(aH(n6THH6XU#mS!o z&8i%TG^9NtyAg{|S0BFC)O4+tRllA08z47orz%S(ixAs;m}E<=*yYh5rzv2G@HB_J z_XH9J7y-jY833m}3TBePBS!&v$)Cx(sbx}!GIq`6=TBu69?vg5Sy6wso<)%RFCPM~ zq55fa69w37Fa2wltyuIJXeW&2uyGO|32lF>Jq=wDi@+d=YED)|)UeW>(;|`~#_<+> zaO6yJlNnK?DO3{@@^HU5MH2+M4B{PHAc`Pd;J|h~G^C~&N?{cj9~o{91`MZAy^Ro- z!cUL}1o+Q`a@h1dAFzcS;|phMKw3GbXbCPDG7P5>r}%pLr?~5wW4)l-Fy6%B$Bb`t zyr(r8`6YA>Q(9;{1DNu#Wnj*R1XLC&nj*H_A~p%qg8Z^4h0ZA$PKQ?}wyfDmk6`$D zP{4mc_V8+lj?p%11g;9S$2o^0LJn!dreL%K+QHO75 z@K90scm=Re|5tH7bbD!71I2t^1|0BtUeOf*=TCx^>|Ct1xDeikWJu4+O@Yanfp!@a>0>fa?15M*ei!K7TiXD2ziY# z5i$o@)9_6pFt;w;Q-J0Ie+6;se+BckfdW@2g2x@tbi$*$S{G>F27d>TE|W)`^p5LI z1-(_itx(tb1oiH`M1=qsR`V_{@K+zf)gN(m$u)_rhWye-=Q-+j@h9cvx4&mcJ} z;!h`E)S~ZP#WnR+t52$KxjYp+q{kscbIV-(&zEAB$@;LUjsG`t$%@)7Tbn~RH^g{$ zr}`L^SQda&C?SB=58yv@!AyiLYxLq++UTL2f)EI)Ua%wIQ0lVVwWmx6Gm{ATL!y%Z zga2635(2hRx^_q4Qbk4+nSP{5N&_%GRWwAkt~cE&F5Wx{{#UpPy*C-&inS zfusi(h1P1wpg!wZRnrs3?ng(C+}m1t?_TyRVTsJtQrnGgwrN8+u=S5rkg0rT_7NhY z?MIWDeY^m(wT`RZEf4jip1>fs9w80ic=G|+f&2Rq_>Zgln`S|Edp;?5(v1#Z!#?mq2 zi$GM8e0B#gfBYPA~I3dY-#!>Jo8f#C6=A2rFXFB{9ZVJtbs~rifc}k;SNW0 zfzGUEj1z;Lo`b3c%Vo+IKdVee@L#~PR5w;C9kERSvC-QI=35iJG-HAcbI%LfCj^%Lp4Sf{O9B%PJP^YeEL|M9E{#BI^zuO7XKL zl8XBy3KFtKd^MTdg*pSeq3gE}!~pe3;x~4O$hs?IBwhrlIuRq$M1Uk@goI}@eha+= z%?@I7a$kGSw!TFE3Gix1JW#I=-V2j|3N#MF4MPFM3&DSD2H+23!(IxpW7N@BfRkr_ z0R<7K;z73BG1B4*c#ahEDL4Zi2bdoe3&1-@{rr;}kfH$3XQ&>)oaQf3ule}|^EB`u z-o|ez8}~L%*qJLs2N*lpGO0u`HKKOF-XD6OzaUz@OWHM5?-Bz~FrVX|HV?YM(g@bn z{`?J+gE_Q4S|b4RAN+^*QB%EOKHx9L4jrL83{f0RNdx`~ljSL=YC~-Wn;HV6E|#MY z{A}>byTg`4$O9%wM?Q=A9BrYNObSMk=erP9Ei`vFb5(|~Kwjaw3&a$Jf<>QztVQGo z|0RIttSJ;K0+Jve_^IGsA>?9gRHs$hHTbWl$s8}?RZgtd3JU4H@`(B%>W;cE7pXpx z7JU{+0d)p-RqB$sRR^H$IF&O5s87cST#Wy6<+sg<0Ps&@xbq4Zzma-79-*J2I3iUh z+&+&MH5C3Y{yt@t;FJ61RS1ApILQ>&>SDg!TaAJAj<*|vNdj5^wfn-6nlpzoMvE8% zCCkMjhfXduJ8Dvo?g0Ek84B3m??(#^8)}Fe0GXU0INf0h;tsQxY)FL1fWn0sfxl&s z3@I)M|2w{LA1}QA;cG)L+fz>D zAumB__DNWAOeE_$cONqE2C-7I{VQaM4`|-qRD4a z!Ws|Pgy}>AE5-(sv08!}(hX&V4CVXUa#6Ev?~B_EMc*H@p*PaarUy;~N0L45>5Sis zGN0wYmRJ&US(RcAU*8u3PVx;CB0svh6eF!f_5&5qI90$mUlXAJi^Nh{e}zB!(eH$wHHYDqU#zwQH)D}44yppyiHwU0{(rzC>Ho-kn0zQ z#~=LXvKie98?L6SOAMk{%dabLx9hufx{2a2JbcD#d`!7uKFwdQ9KMSSfDYPX42L5^ zZn~lyZNCt$QUaj!Z1drtD|$Rv7<`2n0{Jy#E>t~K+~NXZlx@HCf&qVN@;bKn(#s2^ zoX2g|yPs&D8f?vG$Sdo_f$)KXHQm8k4;}ba^pekquDUyXHQQTYq!o|BGGC$qTSb^5 zVz9^s{*KvI7n!qopRcxl5x@b;Kuh37VH&sGmjkGWb=SgyLVooeu!uvwN`b!v^guj@ zi?v$7aRw)H(vlDa<6WHWih7Ae4H+xA4fuDw@b)D+6KUa#gc#Sz7H12C3dr?AIJ3)* zhx@##0#6qRJCbmxvefk!DrBf`EVr%;b3H-bS$u`sBMyJ0JEo+0xog6LSfjp1*EQV! z0Xf68>k$X*<^1aS$@1mPkCmX1u;Nn*Ukw;YTycnX&y4Nl`x#RFy4e~NMw4i5V<24s ztqLFn_;OGVusKNW4x>B3fv$jjgF|(l7!6RS;_83ZeZU{jTO(m@$n3bv#qji<9aK5IA^d!Oi$#L!{c zDaL33o0(LiG`2IDw0)RLT8E-9@zv|5o%#{MA%sUTyQT2fq!46Sw*3YpRGyC?Hjb~Q$d z$jHdbm*!@^dfz$sJLi0-atGh+STS}MjtDzWYAELtRHYxfaE~rv`1zCNKt0H*0xM+G zFi#-=NC83fnx%T4$VP?WXKuOzCLd3p=>S3A0O}X|N|uio&YmouJDWGt3yT7Y#ADJ3 z2C``Tc=-Y5gEQ?i2MYsq1Us5U*jWR>^GEG7Z@e0Bf!Ul|S|>|OmfB@676xe74#GR- zhhnA)D#%?qNqjbMu5;Hgoz{zqEbza?bbx<9od4}f)ri6QSKl~SoEadKlQuV0gz=xY zV}vIuf*d^oh8XOR6Scida3p< zHDx_;T&@4??Jw0oN$c1Lt2aGUvH5}cGlKdMDC815^#+i{^9=IyLng;O|0suV=K^95 z`hq~G4-orL4fg^7Hx4I4;{@Oz`p<^{oMNZ@$%UaS4taF3oqp}l;@ogl0pD(cRIpL_ z?`S9ma4D5?56Cl`x2&N${P(jAA-OY2hP^sIJVh^x8I5~^I?*jWCX4^mZ`fgL*7hm( z3$$PJ9@rB#0i5Up1VOypqdlWy3@qM2_#xT7XdK2H69uHIfel}7*!ac9XV!IW%6ct_ zPLcVOojGI2vWJ@Rv9SXCF2yhbB!x;Q&LO|D{RfM7Q2ZN$zhVTD#V{Wy!~|wpT6#8_N9OI@Bd_A<;5+-MdV13GK3T5sw}Y`N0}FJ zFx2$b|MsK5_>X^iG-;($~sYGx4i zm2+LS>7J(av987b)^txpx&?s+uo^)*SSCmt{A9>&cq;f1OaSOj%oIGg^h-qBI%Ydg z-8gmW+wTqi_=9tI&Y;%pmf=f`G`QA9wE7+FljDdMx$)LYS^-o*}D0Doo&^2z5KfVlkmV|d-Dal%wn z#)THa;BSpV?~^cz`>k+>Rj$pcZvyzQ`4L6I$siS$GA?*009@6$2&s_*ie}wxGt~jq zS(E(3EJpZGa~YZ~&UT}3NnO?cbS<&beIxO=ot?7z-rYNTjr2E+U-x;k0g~ z*)BQ>R7)M4O3)R3_arGa(guOS>%4ISOGmP+I?bWvK%4m4W-={7cm<26TT$s`t^viw zO+jh)XHTln3-MpVzC@k)f5WourI4BIdWN^yRlM9=wAcv^MY<89&9sJTxYNzoT|C_p zTkH@$wV=5J%#s8dCJOo2rR54!3?>V?Gq5_Xd&d=AM)?z+3Qi$*Kp29NGfg0@Ty^7o zL8kXmsujdmRWAbLtt;s5e;H1j<$)wFFi=7dcEeB`4mF$6@D`3Y11+P(Fc8lPTQ`4q5#PpBT^G%IoZhQ}xaNvwd!6OS{NQcgmax`#8}v(KOOe24%OLE z+ll4!#*693>M{3Dlx%p6pT}Qg0{GKRK=ct@L}vBM(aWycwzJ6T(se@fL3IF0p@>dD zer)}Yw{npHJvi2xH{P2+LTYFQ-P`E_O*p`%h8FD_DhBykQ2wDb;Motdi3LQ#pKay> z{7*(F1^TBQ*1ssTRMkwI01HJ%NsqXLnYIzs9WqG!}_)n~f8ubu9?b{yoXUTlSYuOcmy2Dk_#*KueO5un|Yn2$>cmI|K3FcI{Nt z(g3bLR1#{*KqVr~$os$`0r>Gu1?^zUmJkPqK_WcbB8rJTpP4$mWr%bj8m%6#j6csp zeh&0L*`yc+Ahd3wu6nU9K3fHI4uiq?38&JPMq)eU0&)B-WR4^^A=QyzXkTtcy@BW| z4TwpwA&Uk)*Ylfkfsi0g!zEL=cd&E0^=M^=^V8WIg4GQT&7zK zX?Z}I@KoaqA3gucA6@Ud-j52UdYw-s6q}wZL+L`bV{^&^f+PVynfP!)OdA1TrXB!Y z{z4Ou@zKc|Dk-SjLKD01b{{2UOr215E1K_i+)F=jM-n@^lrDMZrFVY#E=q1>hZ3z| zYJctkOayaL3N+kS4Lmf!ha~&1ureeraVIz=z z$WAs^ES-h9;zcodYzj<14vg?WnGbKnY~?_*fku%oyTi}7EIW{&KQ-wdL_|FYB2?~{n4glvW2)|__iI6_ zsc!ykJzW((d5sF+>||TvQp+>v_Ji$Tt;%||b_?kDSXCBs0pyDOa^?DauqE`m9bAY^ zHd_#&oM+DO={GS0bJBMGO>cC&?$h|yp`Lk?~|MPR<(d>nrZUiQPga?@F&Llv=W3tT}~0?JU_=H|bb&W&V7ufe`t6#?M#(Slw2>{q-%o92kUNaKXVp?xr<9?T>ZD2_cp8CBT~!ATbFAC4gzkv&pT%zC_1tw54x6pm$$#mVy_Vx<5v zLFCcGtlXmbi>V#IdI?W7ss8{fS2=Rg0eU;oR0PSX>z$3c~{`Pz<|{y+PxfAb&y z_kS4v^+^bAIu!4oD%f|W5b4pv*&4`=mgSzV<>Rm=v<9Z%E^XPN+$FP|mYOj^1QOuM z_QXuUhaAmFqz<-$2?fdjiRDh*(TW9h465=bl*~h58uo*LEcuhvHBdOfBm%pDdOsUL zjYw>`CNP0`!E^%JpCm@Gnk;v^mXHjILTU3%Q}7=JsY__v?3JdHP{y8o&o;lsJ zWY3#*cQBHLumWir0u@as`BECtonR;0*VJN5pC?Vme$DQQ zGUd{fPD4`tcmd&f>R43>kZI+1a{i~PfO=9l`8t@q;A21@)-0&*PhHok@0*B8>Vee# zu^8MJp+I!(z zWYm@goj1OS{J92703e|97f79UocBbdRbc?th2{?f5RCwiO zp>Q}>LXrgjbAo1du2!t)0!9)k*Y9daM9-fVn@2aq)g18(@m zJ~CXjwV_P_LGDOHLZM~If$*s=9(vUBMIEDVHYJLgYkg^V5xbG>MMw~NNDT4+bDaO^ zz=C0i4g-p9hq;MXjF*`q>wTFFA5HU^QEcSc+XE2P- zCMIm~r@viv%xniw7e2MwBRkz6xoS*Bi%DBAdSyHKF(y`Yv3F)y6dbb*$`ESSud7k5 z_m^8YZn&^_%iFm${W&_;ab&cG9$rUD4Rt2qz;Jx;a2csVo8HUIx|qX)?}4jt;LlpM zV6HB}QbR3ANCk;Qc{{G;l3YOz4$0LN3va(nUMPLUkW8=K=KAPu9hVRU&4tOb$V%mB zP2}Qq@f+u#d4H;q-oF3t=l?);D*Yk}7BiivSm4BmFM{)*{`q%lx6zX6ro0#QYr5VG z=wUlhlYm5}Ae2zT-pPVpsRDYz{P53z69~fouJjelk{-YD02|#$hN@;F*s1e=;)jv-CNViMD>|ZmCVtNon|hLBvSGoumXyA@a%I6C@6g>Qw`=*g+~m6bBm?S+#rU8Hbco$ zxIRLzyjZ2tPC{F?z~o3%Vve*T5-AaXlb9#NCiPU*R;Cu7zi6}p#gFRcb~2ry`}Rzh z;P&Id6G&1+x>UX-=~iB*No5|xb6p^JC9?tleN%-@MbVcaJ`3g(u{}JEfADk#{ZL~G^3K+7ku(7l}~3EE#rmz(I!4ulF8>bI?nKh4ko0TNECHxLbk z|9P@X;B1S*QHU@BZ^NG~-bQfbD*PI-dz=pgtlsYp`05bGh5Rnb#}L)S>6#6L(*SkB zE4xdG|GI(@Y?Wa5V0iENg9IM?G-aH7jV^Tft~}Oni*ovw*46$VX((fg+j9; z7C@{nd;Eh1^(}oUjNmLRM`_9Amt-# zBxgsuaAztHlR?jSpaZWDj~!y41-A|S=jREH47*-6MK{=5CJr6fkN@^x{~n^CfBEzO z@%YMV5Qa=nc!r!2r2`c#;%BO@01Jsmg+ryk`+xoGKl}M#{Olipw($E43F?=pD<~_@ zo+T-$dhXwR+;{c7GUTW0KyM0QJFXo=dWh&D0cC`O_fIKV2oWR@29_9*A=sCrV}*+ul?xa z&`(Cu>VN(AxfgGoJbk0Tb>$eDq9h|Br$cco0?Yd+8xKuUgw@LwpkRg+M-e;9z|1tj z%#-Q~OGbJ>mqlS7(SD4S6$0=bF$d8?)Ehj9@MmtKVyh;;#{+5de5$AskQ^M1(x$2i zg=3hg6vLXpD`M$L*HnY8+5Vi_6QxVg^(}DwJ5q5-nA+v;vHvRBaq}dE7(rWnej2Ph z{8wfge^QN02S%D|9nI9LlVggo>=6KV*M#PwP)tlcn7|&Af>1FD|7c1anW33WXX)bk z#NrDy@T$6gw({Bu(p-u2?n%~c8Y%+4sSeyMG;QnwW+U+cO}Pql2v@%uvc)4&CgzOG>l`#lgvAjmQj z0|*rYht#xZB!oO6&VW?r{Q{~&Kew=Lu*pXTWp@4WV1<}%u@oc!=PK%&>H2{AmZ+-MOZ}oqumQ z`COR`nhEeR0%Pp$?)RT4{I|tD7Zwa=Uq@Vk zUl0>v5~qQ5X*i6~^R&pNdP)?6WP<~#3fdLz9;x1Tr7Y_bEe7%w6sF?-QaQiDjh7E2 za*LO>dpw5@GIg0w;;N;i_4J4@xI#0;#LJ((_3!_mzv;Pqrfj0=$OuYbZ(=96QD+ zP{~Wh`IDHhLJ70#JA)Qz&kf3@&%FHI*Wdl&yO)3T{;l6#`d5GdTmSff|NVdeKmWz$ z&%Soy&C76A)Fr&b2aSfC+&P6A^;ZzxhF_u~3+Xzz z;zX-)DhRy{6E9|P=k;&)yJjw zj!Mi8|dZ8KcITg}gXr_&D%aObxf+DLh~W;QY5< zMB1?!&c7(tj<64{+nYapq4wrEayjTDux+rE+@3GhYZbceZs|N59xeY%M@@x8pFbfLN$8@KFf02VwTXk+yi2MyDGpx{o}n1JRFE z2C1rk0MJCyg-iM30w@%7vkh$hJ2cCpD}?8A7Vv8f{F(=`aoWi3Et#cQga3AzoohGp z*RgNMtN?49rt#_Os7ULrcYZ!!mebb$YTZ`us8~SNX6z%$U~q#fD2Q)lt|!pQzJ7oeyR*r)IIzR?8SBiW(0Sf&uaDVS0rL#k@W zsM?Bcxso7H?4<81AmQ2IUi?cV49G2qxa4r>>go#0ZrVKO}D;cjDxO;x|_cO2l=-uX1NpjrOd06n4?qiFgE&N+O2%`NVuFg91qL-bqHvf=8Mvq+|@Y zvv6ARP{O99|LH`^nQ37&RRMeB0phS;i1tt*Kxr+) z)Pdon5jZCh(7XY$C1y|v(kIvqvziL z{-xnx9~}I(u@8Pcbmr@45&5Z|Zlj?LR)aA!(KtFy6jG#(On_>{6i_CnKnNRR9NL7~ zD8Y!LX{qQGEOeou~KB_fXXlz()V%>Zd`D?wa z(xpxb`+&e8f2v^bq_C8v8Y*gw=Z`VtV6KEqk2n&KMk%zk7r^;xno(+Q0*aC>L^33X zrevWD`h_fg3`g#K>)}i-<-G)qNaLhuT*uXubs74sDcw{?)^+nCmA4?>sV0n5#h^XV zjZpJ$3dfSw{MP~0CjKMY|CE%U2?-%vfdS&%=j+3hhhyA1spMgXP3=Hp@dCl$eMzPC zmr!xMa*R1k;c{om{ByJLpi`83Fk`F#HPXx~Q&_`5pdeIjV;cFyUa){>%a{9Yr7=ks|v1 zl0k>ux@dow+Kf-|H`YU_gt>dzSZ>9*#nPMY*|++ z`4_~T*Hu3Q_&-=D7y6;*9f|_iZT?cjrf2ImJ=7@OU=Sm~B4vr((y}uUKc)j^pw@_$l1i`N7@c|a+n+8D*a`;6D~>~ z21>%2k=>CsuN14zSNUY~jt$T4+4V;0;X%6ZbsrgNIB>cA@JND=EzC5T2w(zOBX>iZ zDCt1_yFTp{f#kXF2FAANVdqxj$pA;K_(J7jtdba|MB`8cM zn)a*xJ=X@1`h>tis~;r?`qcu$B#4sy1H2m!dMUU&di*dmg*iuS6Qy zAp*y#xGHBe)dw;)WYi>P+fhcPDI|IRwQ~qi)KQvLGS>z9b9C_-jw`VM!V1Kc$$FI) zm~Uqy0||qRPFNF|rQ;h|3XtxeE+SaZ_(k2MMG7&h+*CbrVd?G6wvypPh@2h`s8ukt zAQd0*k1h8y7oZmGK&Bdp9|OU35)O?R5S4eWD<|Ik@q2xD&Y&zRji9tkOjQkU?V)rl zDnQ(wh)jG@oxDJGg^dWlll;l76BCe%p~=P?Yr9%9l?_%6q!9_UfsQ+b>Y~u3s}rI=#TbRLT6em#CH-O}vA3~it&adw=e_HRoJC`U z`*Ix_l+d*fxcATm+=Ks)@8VMa;?ZZfVXS#@|EE2y;eYfjzpc~FKtx`t?Fp{z?i>35 z`qo0-Aq8~otG92Q$MN^YhN_!n{2BIqp?v+;7mn-#&^!oX`K{zn9PeR1Zp_xcz{?I!j(I;9r^z+8LGWly3;kultC3jY80``3;T%v}6SI^=gQb9lbD0rnsy=}T zWE==ZS*Yj3Ggp3`Y~jZ{RdsY)O{~1%TqF zcD)-0M$!|RTIK>Q^ps(yz$r`zm}oGOiOs52840Ma8%rJ1^Z-5(2i$>jLO)m4D|(6! z^|OtD|M8E`bl&V`_QCiu3MlDGmM2w-N)MIJOe=_DbS|q?3{OD~7vN0P5~4mIKbD!o zlCJliHyGTllsEK?Gu zSD3#%QlaKLi#fDkIM#$() zB`6#N=P46AG*-mpkV~up5Z_3um{B1p0bRod#SpqbF^&|EJpb)i&wc9^%7?X+FilEg zZv6A0-h+ZfY`&Y&Lt?45e&u+_o#$fnT_hKg(Nuo*e9g)Q8l%VQN4#)~99Pm!9kJhq z{VH1OAdEuXIezU--dz9o(dumzrKopqxR{F`Mad$C18vMo9GNc@uxTVup1&*aMdS_g z2VMxCpHKyr0><`}JF%I1`O!F3($dDTJ zUj_e*rjG3yOtgRR!h<-&HJd2xqU4_+xLjpzND~HpFi;A?K`x?vdk(u7iaA$`0S-$6 z1b?FO44mbWP5v-&(zC2z~0?BrmSA}D@*_R=BTbt<+f zbfO9%^M@<9|KgkE{9_cz(%e3d=x70o5QO${hSBrES47wiPk7I0{-HFA4F!j!%v?#E zc!V0zUN}0Vo`xsC^Y-`u^n0Y@kV}c``|F>5@Vo!;Cx7@K|Ez7X2dz%30B8X~{V5xO zKglz1{OSk4g*G^R${)(m^Iz=5S0}bYX#f#wX*qKOl-miV<762^6Cil!c`DE` z6AepUWR#UptMGw;n;q$*;@K94N_sOS63IdYBdV@;cYS)k|C_JW-Z)99{f!zelhXyY)JdMG?< z;Xvs#Y-kDD6@NNFTkx0CpP~K5 zxD)M-4vg3CPvPBaf)na;8|~(7>-w)$ZH6s;pzYcHAH?>)SCN;5r0p#j>!i8_x`w&) zu1lr6E+%#lmLW5{d#H5pNL&dOqfqokIR8us;Dw%fUwT0Y_&({&TI5HVSK%O<*XorHsY9gPhi=`_WC&;f5EhPVBIYJXS^Gf*P zQ|b}O+d<)BrkVrr>d6;^1tKubf-}rcNDK&eQp)#D#i^bq(@D`!1l(qtsKb5nyDvTe z{g=rdawJd8$z5`8sU{969c3Dc$%4t0?$$50tH1CZoe0``ueKjsYGDpiHYZ>G;Ed{a z$pUJ-*44b+#aZx67L~?$VY8Tes9F468=*;cEgvtX!DW@d*hJ7)X`k2* zaDK6C-((&7Hn3`F?qN;fg)kp5_PG6s=kWc)((IjZMH5MN<5IR~s*2GPzfcFRR6-Iu z$$Yx&A`r2ge1owHi#Rh4+%_g^eJjm_CJK>dQy5|@fPEPV>IEUYR;b+3)^8CHHmX*(#wht9y^8A(LkHSOI-l6h>>GrZrck}h<+CO@!bYbAg zSZnN7Z`KQko=9w@wwI~BaX#{0Ln;O+3q*cGXE=&2;9Gzp4p9XN&YfNt3%jV_2Ud1* z^TQ2<%ixp>stiDC#!^}!Na2=q~X8Qu9OJ~(22`Bo5BdqYh}Y0jl=k{)Yzj)7ZL;mE+!y|2|_rQA}94y*k1^91m#n=}9k1IM!s;6Wkn9-Y95WenM z>CUNAgr>KQav{OKFWDL_yFM3^V3yP)<)o_RVx^?OU7 z{ppYI{K2O;{`4c_5#$K*DZ+6T%g7g0LwB$TAvg+`C?!TRj>!dW3sj&==o8stDw1%> zU1pAEC}DUP6Tp5rE8v<1YzL8u-a1ny#S8|(6hEK@HqaQyZFDiB4PS`;Zo3Z!9!R!WM|Xc} zR=#qaI5;A5vBl$XK4eTG<4ok5C;(J{(HzCU{nU#wW5O_j?K_bhVp^1p^PfzIN2~^^ zuoV3AuS?Q`D!eX9&y&cJ%ohLuL(ByVg5)13>F@C$&WE3jEANu~q(tjW`3HvSsai+h z_KKzBEq7jIK^c4RmCF1ZoxfD~)T88Y)IJUJKY%!-gGzw_oCAPX?F4~;LEMv14H-b8 zz@rZ7bgY13yPR#qcDFXXwU4~_Xv`0n5*%^IaM7P3s0ukl@CV#%+wajx4Dli$X*g-{ zs8d45!}hS&z>Fz!$ge#(>Lk6mo36U(j;pbe7zo=F;bz-Sb@$K&2;NtFpXnWb?!sYq zK|b|Qfp=|q>k*qj1ApF6SnkDtKOX;3b_M^ZJroyQy|M#;KPuhbg>)6iah5`-*q7yA zroRO{-ABTIJ$uBM@{x`6p-Q@cVu1K}lA!3i`b|6DD9n00cjr)5$;|QC)QOxc&AGz} zER-J{CL^ef8nJ^T2^R1l)fZAj$xkCRoOSUi><|<>5nC11JCFzeElpHe4dgSsxB#e2 z%8)vDkfGs9#;j^g{4k~Tu6|0oyQud$R7YU{8!F;SA&*LJ8CkluQQ)^5D5~-)7WBlp8W^iA z$|+UdqScS!19Ef37sv&oZ=*W7%(p_GK**D%1O|e5&?(ft!bspeV+fE+-~ibjlt?FH zF#LdF-dr=n%S2JRd*f0wkqesnDocMEwVZm!nKM;FsRiQ6a!W2PZkPM0;i5`QpQ@t@qI{G@HOhohenr!zeo_{~Y<#tRWG^%(L5q~PzXjDp-S@n&xEW80s0KLQV(%p%r;|+Jt zRoOKIZC6#$T;YHS;C-%f!L^`9Qs)J^Ux&Pv7>H0?)pO222!{mZhV$9PY~=YwOau+3-cMEd30jG&^YuPJ!Gu{ zg`-mp*jLw~Q*DQ__Wrim19uAGk1GzC*u}Xo>E$dM5A2HNi$;nCz$m)0+W=OF;l^fY zZ1Ck#i$DF~?Gadmw9XtvrUPd9+ylzig#5f^D-p2`UW;>dZL&a^!(hgIMEx1L-V)x#2%- zKMUK~1z?|#04VT{9}zYJCyF&}06TH52?Xb$06!w(Aix}_ac2se^vIs6qHV)D$bka> z=t$6dOhSn4N#+Ci;D!`_kor$o@0U~~VTFPtvy35U>v-;l@uRi3I)CGD|HapSFih7f z;WjdKL?Tpbnv03SQEa}}LrEII$joBDjCgR)HPSV*?1UFn3_ zKS<&el=4KLFfd((uTBCd_)k_0qzW|)P&8!4( zB1~5U)KV6uiy55=I1<61sVWZRc!Z`=mL^-tipa=d$M3~L9iA*Afrp9!2^Y^a;q7lJ8c4ShU&z#h|9I)VVXbM@i{KLF z08TrOYAL#9aeeNKaUuPZch0kuoXHEUUheAn@OfQ)v+uK4dcXBr^W6*Na6-#4U!Wlc)E{<`nP%zY zvF6(^*57&_(uue>ZCSv4w0+924G_RZ4k%})_uwRcKB+#=`P>=qaB!-=00)$%7o3Y0DZc1pEp366Yo1hXre>wks&~(#EA^{}4^|niI3VtslP7`SsVz7W(%ORadMGeD$S0aJEm>ZzEdA zZyB(9ykRTQfwY%FF5Iu^UjttH06Kv6Ko_GvVGqQD zU0E)%6E5b~LL~0)@ZW%iW3)K@54OWm-T$YdDEk?zM(bR94|lecwQ(98j76}EfXsGl zGXW0y1^#xfAGSRpPb9z$>HYBf2Cb`Wf4g8K%$VXt1AqUD?%4>V*ubyw-@QH7_GrfT z*fwkXl$RfkzuO@B$iuY_z`)->8c)X~>%k5G;dc0T$~KD1bNFv}cW=oV1gZ+veUiiyC1bRb>80=VXC zF8V-XJjSaGc=s$2yp5Jg>VoB|;-cfS!Uf@b6D9yW)mmkysb{h4?eDz)&JW+BXFWk! z7!rmAUWrASMi03PSZ0KrNKhEKlXtDQhAjmPZDjHTZXAQ@VNOH|TlHLR*R{6xYwe&k z9Fb-R*fP2&pq%D>X2@;K1g&t$IK{HS(&R22qtouLWP|L*WDGrRS_uHoLT^f|$a|dW z&Q>x^3o{5bLP7q9`39t|DUQQ@5IjYLLgHx?Sa5xPB*`;*0VfY)jwzZZIiKp<@i-Eo zDwRS%XQ3Ym#rfwJxYMSPd|XDK{ zORt`eEuKY&nz{g(G?Mu@j7ZE4-(DoAg1q?u2T^!n8+sqi2l>ehQj*VLQPw5Rh3ShV z@F$ys9*%(jU=CAheoe)xmWGwnop)csNYOHE`^7}#$7laZ+hdPcZdWx{#fHbLw@B5^ zf#g?f#a)o|PmTXqn&blu_8qaz0k#-`1W@Vv8yfh4JO)kRA*g7$YC;-E-W`REifcN3Q z9jR*q*YQne0yKU{dYE6$r@_?%!Y7OxxcxQ^yS}ai!Bt~j-Gjh{y$yrwRRiixBz0<`c&xomv%muoj{dEr3T>qmB8Ok|ID#%4|yO!nkW z)E&H1K_4;v^Znp9us;-MA^^pD2w}I0N>WNl4p9S+$vW03LeLkC>KnixKi}pB2!z6& z5(^+S%#6SphywgHoKoiRcxyl(3p5Mn07wDVaXWVp6W61ZfYc+k6@&1hpmZ z03>l83o}(H{}32ew&8FA-AsmmGkNJZC#vT$IxtBhik(%gv=f)jqANgLC)J41dC_sG9`f^9 z1KQSH5@MVM=O6sXC}08<6rQf9i1_5kr!M~VgU)N+qz2IkO`SApb_1*KUzws5mC9MnmH|1|TWK%-zLUNl?j8gWWpADqW~ zcZ3YQiY6D}t=ey8+SH{zRYNRWrhI}o!yJUV>|+otIMoMJO`Iia$R#+*pHGTWhm8km zaj?;yP_tl4*yel1z^Cd&DCuC%l1b%Ws6bTTI0aAAa`&a)ufNV@;oSEwp8M{51K)VL ze6dsY#S;|7A^oAwT;&UAkAM5kuCG6zxH^D_TglRSQayq6!nqSU)0zQk&N4~A;AS0v z{RCnc6gD#5Aia}9Hs~NQAJx+xqvfbNleZ&!A4Qar61G{W=K|y@1jFs8)Qf*_Vj?Vj zM4B|nufpCd*#y+KqwRm?2y9grTDVNE$7}MZ8p-oP!#}>K;4EXDhbj- zq1zI0DZvlcrT4SV?>hM9%Et@bJP$j5L$G6uqu;~*VsBXNn*M5hYIeb`u@QLw8v%bM zmN?kNhXg=u0Yl`MO5}NUF#dM5T(L{BN0)WC<6!yuk&F1NNvhhRlLIJj7e*FB+~x}Q z$o2@H68HOqjnH_Ry%SnG6Q*Gpz`CclgZ%~lMZ)*9Y7;r#3<^jqunjTaZ(thqux@zK z_ZeK=%^(c_?NV~xLGPIB+j~F$yX)v&m)_}KZ}5isI&=l5a>mP*t~U!}PYQ;w8G|3p z=Wf`+_Pn?O1ehMESpOi!gPpt9pWnaxQpw)Is>00i{K=l2WF2~*hc1;L9jrz&VlQ>R zBXO#RSrZgcsis+hR5e{Q4F3(}L*`$Q4mqRW!cZaL&jPB;lOHbNNUQ?~u!f4!{M{|! zza7b1{l(CK8@&hrF$87;pjkv>C(H51p@x8T`UoKJOe!go)bjk%>~f?%xJ|fFiI)`Q z0?X5t5GgeORRJ1`?jw1~yI}~h2wb!M?#b4h$MZ)jK}hBfL@*(yn0iFhPQX~he>b5B z2!Dfa<#~ov1I-Q`1w^I|wt#XiB?yft)Wu-hwMwV2E_{WufGU7ukN;RS;E~V(0M5%{ zNs$uvWyTRZfedK8wpc1-gy#MlY0`Lb73Qa*%OIHxQYHY2n;GQr(el6+li0{=b4!0+rm(^;2(4y_MPx%=Z$B z*gvkAxQ&)z2V+Bfjb`qN@AQB6H9A)^se!gSm~K9jQR5h_05nwbk~A@>|0UrQVWsUO3FsYC zQn@eLKIH1F8w+!UWF_nn3#$IA{0;HnECNP>1^ma!QIa!h5-tS-&R-3@F6V3*KD={? zPORnIFBalTLHL(Wb+&x?T;rV!g_(9Te-4e;ZGI^q0f)!xw|uGUnKeM<|FoZN^vCNz z`rHk}J@AK5IV*&MRTu|#quwCLM6cs-XD52Nb|@X3XvbhF4Dgv;h(~hnx9}>&|0wdC zXB%BJ3>^^i-oZ7)DS#h_jZOZl!&NTsm*^huYfxz$wzlC3>%t{^uHUu|Zlog({2ksJ z>H_;V7qAE9V6KKSGHdA9!RvDVeDrp9K}>+f*0sh2I18ogtg&&SEl}jwA-`;prNWjz ziv5art+}|pNjCu$$wn191S2XLG>KbRw*kqxtglguh?GrV zZ1x0_L8yji4<`;wFG4I(G%pAr9)?G5e6oV3u7m>|!XpihgDo8);GM7+i9@VO5cR^* zs`iB}rC2!ZFU%fLU5+{zp)ZC@A61muIsfwisS6IL05Soid6fA8?^;p?$j6BnqW{ZK z5!IAz7-C}-umZpo_|L)yWytM!21J-7=@eN@0dM&NGSQ4yBA={_=2WpoheK~3H)KWo= zgUNtD39H~an2hI-kz&Cv;7HpA*-zIPB!w1Ay((U8Y3x>_Iu1kxW%`ai$pL6!ApNl9+t)2(m!FmM#=!p7ugy77dI7rQAUAjh5=3hn{^0RJAG!c7lOS0M*fwA53w*k8KPUv=YD zp5cqD!$tRPCj7`*Q37SCT(Cm!pxxqes4z^(Ha48GvJrF_Qyk+~y z`A4*WNVSlVLdy1W+Mc1FLq6%9Qq3A9XRINSZmGQ1-SzPcP0KGHNufe-lK21GVlVJj`CUB=CZhZ6?E!2v9WWR311P%*fKVa;mz#EVZ&iyvr;9$G5U$34X zI{zO3?HB;Wh6hY(3Bg~e6~%w9?1Uzw12CJyt+|vRwr%(U_zm{kW15wbq49S#&)=~( z0fzfe9eCQ2Hcr;TiIHRcp4De@zIuTC=Bqor z%)|N%jmKFfdkHdd?m=V}_=rbyBLV!^l|G||^j$KzD2sM+2OaYZCQAO+wqb9NtH{^swDXI`5XfH|Ra1Zf2e$ zjMFk$QgV>n(CI7yFW`x9&z!>CRFaD@CGuv;0wrnFMS=Z<0HwN?lG#idVGLch~*OH&MZm?D= zhs9|PAxYFmudcGi4odl&uAjsZG~A-Xw~vZl6q~c>Itc7G+#dnW48ULcc` z84AH)5`Oki)GM~1ar>@03#pruZb+d%QH%2D9_oCPl{?1EEzZkfqZB|^vG^IAcY)5?jMtl=(#qSD1z}G z4E$F~b-Z-&&|uT8?QPgKMVq(?NN|fVbZh%RXB{HH{B0LzWdlPHus~rY0=Hvq?!Dbp zhwCjS8~40P4mL=S*c}_E*(|0}_6Wgi=e30O*BVK<_{m7{jC|vf2bcM9FOW|IQy6|~ z$4A#@Yv>)Ls&L}$HJfb@YwFGSy;r>bt^7TgYqC=VIgnW z`$x(Tj#clX*Zh@265CYpJFE}@L1Cr<_;_X%z;k}fU;>M6I3G{pU?>jo#2`iTp{_9* zpSszETvOV%u7Q32+%l$x>PzXjkLKfWq9C++RD3=nLgWJBx1&U-l>6~Q@E;DDOOeuJ z?dbtVIolH@iWH0&LnVR#hWy~68ii1p;F^Yja(pBQ-g)n^F$`FGap*aOAz*Xe$s+=6 zg|{SvIwFYVPe5CNfC(fT1gD~*rkEq(lh;6x6wWomu^{G#A`oHLs@WPe;)vLi{DYHU zINw6pR}%_u#{gy|WJe&tiAA7MK-OiIJmgd{JeUbksM88fSSaju!af8hxGA@T# z0HIuPxj|HHfo5cI@~GdZ0_5$CtF_lJ&!XN;+m6R7lxtMIV48yzJI3%I z4Dmn|;C~3<9)|PE(AcbZ72pbr1p=EJZ;yNDv((yS`TVf0M2>f&av{wbehzK8uApP`k z*Ihp;;XfaZ=3y6%1p>Rc0)?ft*kIPcWI;KlWBFwGaEiE{(L&3(N`HR z%rCfL#kCVW4s?wK8OAibq~ZX+i1`9)6?u!TO}8)9-a11f5GhP#7Ht|S+Ay5Gd7PxO zDx$!0_$R9^Z&S7-RYiId)`whW91;b22TLG-2m~A9Paqg`VE(^l_$$d@iTycB@4Q?{ zDaz5Yx}tP@>%!^EJI~jC`~rnzM@MS%Z*)EJ-0m+{J@shCmaoKz*+wa$~Lhu-IBW+tdoi}LU;4czDljC`mUJ?R6hpmBv07)Fc3TBPyh~TPS zc@5wIjE0RKpfn!fH=H|!BU#P5WKVD@25d;~n09XhcoxH0?qx^%wFc&vwJ#yG7tukk zKAEic&l{%M+25SU` z8aF>!{*3<3DmFQyY2#zH+x}_QV|(7s-}YASzDo`H$)3Utowe%^kJQjdhSVTT0K##q z5g4z)+aaqN4MY0BKnER~sODFEB&9?|;sP`XV<$$z>;k5NKW)J%5VdqTBYxQG2*7`w zL!3sS18$s!kIWDlvyCSYbZb(8w~rveco9~BI%2$8{&ej&@;LzfXJG@6lr;;5SIipd zQ=pWgRPmN!rTtKJusx;2m>Pignl(5P1I!9YE?}1nt%M@*iUm7mI1dyX+s|2+{}bT9 zIu2`sz`14@m?>c9KvZDUfxkvx1YEGst$wTjHHCLvu(Z!4w zD=!GKeFEz^^HZ?j`Fy_(ADwCb_{G|5XX`#ZS8)T$wPR>ygXA2~Ye9f6Hs3}&lh6QO!Ij9eq)*Dn5Bfhdp_ zs%U4bN-WS=0{r)?K8F7W{wCm0hNrb|!R^mawZ!N9YOb9oy|e53%Lh_zM1iY*<@t5h zk5kY4MERDl#-D}op>xxNl^ft)AF1BL#v`t&w?_;g8x_wG@+|>inm2ea-y+oIw;Y61 zgZfqj4G%s7fqN+zLq%H)y4~Xb6ce=uhYds6X{5)d0=kI3Qa%ms7dQ0-uv!vbfzeiy@s$O= zMh6)(LLaSoMit`m&Fjjye7Sk^`WFvueXnHiNKF+>&NKrj<{k01|~{;cQFM6f6l@{u;_Fby=9HD zV2wFo1C*mqjhiZ;({()n5|!3SVrRNs1iSUAOqFWBK*KB+W(`O#XWCHaB)1czK-v$S zKTk@$10r1jNX-S4sfieB*b)~-bV6Fn^;ivBu>kVL$o^-V(C0)3lNvF=6BB?%VD3QH zjoSOt9yi@cCoEjSEn&2^W}^%lw0!i!BTAM5}2o9I83E~pBPlz?Z_ZVm14eAn$-(^jklgZ@!4A)ch45j)G5a)8HYA>!RtyGA;cVZ57%uSD%+ka zQS$06o$Gs%bk3XaBc&g?S}!I4G>DBmn`Ig5jw}08S>*a^3mR=^pAL$Zq0OIlAAcEgD{vNKHAj=%} z2>5%D;iqlTw+delrMXD3IO@Z|N9z#(-DLy(_a?wDVn`wyB;vSwI5l9z`DfvHSqd0? zY}`F@?ZC=7w3m0yv&en5!8n2i#AD>Pc)a3I+qUNl4^XCG_j2q3?UDaK)|T(;-LvIo_FXMR(*IJ8R6cNbRR8>)KKzD5!o^l4k9Q3T|>RVn970#MCujT zNa`TJYm~TH_;tHXLeUz*hHE$l7~;8+EXtbSDP)lmM9dB>M-<9Mi%dXJEWo6I1SA}O z{C0El$pQt72>WVM;FE<&92(1k(l`7kMqr@?dJVAfkF`o5_HkpD@tE8$?E znAdKhX9?hBB>N_(mp1nlN2Dasr)>y!D##|4EQ-1U;E(wO%o#Zw3g0kUz)Vowk;4Aw z+Ty> zD+497Z48wsMYkbmt|iC%9nW^7-qZETi|2muZtJZx4J*f6Z=b7M8mMGmkfD`)Z{f;` z-BXo-GZ{EdUq4rK^SSuSNv1YOW?P_iq{c9sk3WE+gz6`UlUM**Kw6U3Nc3YGSO}x= zr!9<)MYbU6@_&*ET?F#qk^G=N`OL^6VhdCYh6Lhp9?Xxbx`xY+CTY9V*LeLr$WNXs z>2s)0R4n%Va?O(xB`DkYNcm>(;u=<%>!{zF1GiPY3QYhmp9+3KRG^6;vbm;g2&UHC z>2_{dH>$d!C{6-0wr~YZ20pDJ?Wz?Jhc5*79=KhWH3PeUiGs=6Pn~1TiQH?|tT0*! zYurLjsUlWp&9?4nR{(z^M28Pgd(&nRYL5xcV#BboINN-B5BRH*ZqPzEupKTxCpauj zg|%xk0DF9mw~qh67tzr^skSLAV9&U}K|hXY~P z=QsL~VYa~b7*OlIg(La=jr$%%!w88u|3rS{VOLth6qR?&Egr00|4{SBM~-cM^2NQo z--{g`Y091I$)E1YPqr5%oA+Fd=Zsb=BH-vCG)(Bm!YlwRLL5L2KdwGX!WacI30-$5 zsgR-AmaGEmi5FXp80Q~D01=@SbhiNhEKK=rfoA|uz#no~Fa%(T$OjkLwYUICj<*lU ze8i$ar+WmR0)Vw^G9TGCQNRMCx-@=ipaHf(E&$6}%GgQK%`gV|J9{Bh!Xj=e zrN;EsVZni@jB6Irh6eFJX%~GKi3vzYq)ya?_#8CZk<8uq5G2;8m^sy0_yzw z^8?>~t>?4X>TjP%tMkBg%SPI44dswgoVeM?i9{9vcEY%1?{6O~6=OeAfWd;;2mjT5 zew>=JDxMv;Up-kS(6S)=h=eF%KIigIknXq0uM&HZJr7%Bb2a(@N@>nf>#j@LNcTg2 zqU2UG)mguIy6fXt8tz;mShoL4#r|~d#^B14D=xwkX~IA%H+7G%Sq4kgrf{_=_ycqv{|)f{ zeb?Z>4NRvy&)+;`kDP+da2CJ@$N0nSNOp1~o$emlZ}{hBgPr~&+8?6s{rGRswPt+} z@<-o~S7)`PBfers+S~2!d4w>5ik-YAy{K@&8jpMb(REV21d&K_}YD5c&RR1vBA4r!^2sEV-QX@i&`5?BadLl5NOb?bIWt6G` zQrz)=lcmfEShKBc5P||OiBu`0BQ82Hs-z$fyrApqyuif{%pnKQF&2s!J5&#l--Qe~ zK*xku0O%I-`-7cJZ>EHc2-p#~WO0YFhlR`fE8F#1+aAmZ#bvhO(sLtX69lyt*LF8m z>6vA*B3_DW=!9q}UEJZnrT{WGh{zR~pUut!(~C?Mo|NZn~e9pc8Rip8$7g-+5wix*leXx%l}#of1!m2Viz**K!+6l%Fe zt1Q=M-Ribj+XBg>UIQ@s6Uyo#;eXdC;#B2qa~9xl_|G;wq53VcAMiJ}2il)K)OOZ9gNG#519eK!LL%kRwE@0q9Y`E6#PN{uyzcNLSd|kFDnTX!`Dh>Z1@jdPcF0dG0D=hc7s+F;KK>*If;uC&u&qByeODuLBEJej zf-05{3P;3ZI1k`6FTe-J3dj@2A~J420WhM38~Afxm70HHXPq zgwup5Ag`jj!+$<$HD9ooV{2IlXQ4EGm_%E(6#RGb;$Ex6 zrCBiT03e!3AL3hJ7N!vJXpzNvIUQjN%sSCqLI#p@MY^9#@JYne>JK5;mT4ukQ~@2b zJyT^gHGq53NT~9L8yqVw%v5!L=Y@)!Cshuq+ZLRcvOFs4k2X@gS^B>GCm> zc3SV8C%wPt)0gY6pCB&42$?)ewk|Erx-Fxzjib4nMsq2`#j(fXmk5u+zMln9%nSK% z_d*kuS&!p(cy_i~0DnV%rUP7o7L9N|u3d|p*NhgzFPSZn+pi>_0$L_f6q7wsTaxL7 z?QgnyK5^|7krbwBHJ_Y$pz7Ht;#prRd-~znMpPXL%t5@6R!x>2DB%N<0$vCH=CA?g z`kguq@zz0D;lLT>lqm_pA8-)FrJF66p0TFlikEUVUM1wKAVF!P@`GtW$7mVJEKRt*U?6bD%OvJPWr|3l48qIFx zth&^udywB%7W)f2D3iC$BK!}*A0RbQ6{5Oy9XsIOhg~%~T#$Pio1|l0q{F^AdzR?h zf0h27>$OBpdBg++w!q#M$2egJyPb!9o2M|;VEmyqbdRatowh%^HhZU69lH9#_l~GI z&VUR0*dF&k6U-L%4~g_#{U#)*9;(;t;w97H`EjDdl!=uvnboHoE*#qUX8xg}n%t=_ zvV-!c+mDRb;}M}3B-aS~mnJf!2@{JzFM$fC@Ra4Aj=pig}sU}wWOI-j9+m;jr_ydn(T^!^Jc%7#$ybbZ+NNk{3cEP#vAg66d z_joIyoz4W+}xW2PjC4midhoX2kujD^eL1jFH! zz*~j0nLRPpnnu969qk2_5OBGPpW?A+&!QkIX%0d#d?ON_a~4O2K+`eh{BVT>(+FbI zwKIopMFjA%sRAQj;6esFk_3p=##fIv8OximE~4}x(}b`CGX)41xEG9+3L=uKBPP8kA@-WMy@KUuliWz#*)4~L&K z89oZVxkQU7N(9?(=5D{lHE<#1cWyJ#!AIt2auz>o@L!AkRk-4a98kpPj9$%SzQLwo zA@mQU8-70hcP;Db#)qWJHzPQ$(jX9B*<-^HGVKRsOA#{IXpK?)l!#1KB_ z8vK_b2p`QZvgXR6a~nRws9rlul$Qf3zmkjT~n>-*P(6Rj9X;c z@2fB7;<|gt`S70E!;Nf)!rL%I?_Qu#+RUZ5p5B1k+mJnq3;_H$V`TqV(SbdH%fbID z`Dt~ZA!`Mw1R?E$xW{BJF(gLLDH3x4|6TpB>l$AP z)Jvib?FA|+#!*#O$XHsS)Py=U>#2TUPnr^y|BHY~hR`Nn2>hbV-3RnJ6LL->+Ydv|h2(rawq@3a4QYzG%R*e8tu;Qf# zY8jyPWfTyFqsDXpeq6ho+uKk@br?a}|i$+xV2nw&m+i9BH~ zmgIw^105UpT`4>=LPO7vnyY7N(OY%xbbh*Z_mz0gQq#frY9C2#A<5?p4bObB=9$MU zRl{<_(6F-KjDkPK&f;|T*je0y{~!E^ z)$hekM(+7$*CcbrC$0wjyz_zjB=;~Vp*?Exoc1su$J$DR$tXYd~=i{igI`I;s;LI%8I zfquu0XR+fs#W)HMwr%^9>+mNFhq=t3Kmy36gKAr8tCqh?B`?{YX*vng7NLyAoNDF> zY%6*TM4R(GN~v<;{_#Mt)E*FY#j>CXp^{tllPBZgu&zM(BPq26#v^0L;GIa37#j$UEnR5q`PNIPfAIdv&)zLsLi|nHR$R(* zgk(+F9xKmI)l0FTsxBHLFErQO>?1^516M=277Wi=3`qpuBxmgyi77P~ZJ+US>^sBe zJEHEGwqGbDQ1eBa5GhIIUhWyDO>+$ah?4g{=$eGxSy zO6ei6iy<)HhT>l^U-VA08ajymc>e0rPQ@0?p|cSdAOQ9^4HZexAK!kkK=e*n&r4$$ z%6qjR0e`37ti=97Nu88TwpK0-fcyk`iIOneJvdaAnD3&9^6}=a%#?BRY1)F6))%Xv zeXMdT2w+`$fe|vRA9jx1T0C*wh5wOyeAADVA0sS^!+-u1poIX%h5>><5mW(QI1FG6 zg1IivYd`kjvZ3J+EQE9iNaZgQy{x}}bi)QWL9pAG!&F0O0D7kzd=5`Q~3WK|t7+P!4OoKbKOC|)Is z`2n^&gpa-f@HSi`$A=MTV~V0C#tpzkTsHvSYOmwIQ@f_kr#Qw&qCtkQh~e3QHF2>2 z5XTpNxoW*XKD5#0xaWc z8`Oi1@I?S@6#vaSMDbtr4r)R!YgC$Y0%X|>mH_`<1%cmVo;=qi6bp}`B@}`a_=k(a z6V5$mg9SpK1y>ojALkz=C6i6P4%{%0;=Pg z+eE--0X9h1;Il=~IT8{EUWmB>rwIIA&Z-#&*0z&TaU>)gg$9T!AXC|J?PUG(ar$yP z!z5CRdtpA{<;2@K?IZGh5=&iV?^9yHQZn5_CzpZG-mbfe0f!5S}NKv!c#%lgX$cK zw~r@p@m!b2SdpGSRA$j`dmW9IsWpp*Wcl-m6sD8g8 zaPgBg@VCqvex&*+#D9kmtG{joe-04%hs{CQ=I3na$4}T`O?L^wA6Ns;yx-{2!()zZ z_&@#KZ6o?=bUS)jxL*uaxE-O*9Yos*^>ofp_UmBG_ky{=${`i`v@Dho>mEPguI*|D z{y3|)2=qeyWO#;wx+4RygxE-&g8lZc4F7Fv;|FiUv$5HIxgehgkc(AyhSi%4+X!Y% z5z`iZOYRCHa47F`i~EiuMSptg@cr;0HZkOj*0LH>51w&#sQ$kt@(yw4?N!)edKkJM zk#a~v17rc&LMFedNoP+|EZ|Z`U4ej@UX+Jj$ry$}roq(|yVRg^&UIKMfd~r_0RE~A zaP5XAh7X{*DS+WWYe@z<=HIhD{K-z015D&dH4b|brVk+{q#%M1(P9EzOaWpi0)#ahWS4}3y5QI;4uL#8n(-5;whZ5P<zR=1xyU7o**_5jiqB$0|e8tr_`l_z?mQu+z z*Um!eE+TT|tOmI~DWJYuvYcZvyn57l&~w;2QMxTzwv$3#gqqbgK&d{=0(^wmGJIq& z#>;X3;rXdI+&H9s&W#r(;6vH?Qx^{z)xUZ0;MU7WcB=PW5pztyF!kszJk_oBKICA2MXf0f8vyi}tGz)OU0hDnatPQDHyQB^&xp7V4#k^nh^tdud+Kp^& zK*8`>%sJ%Z!H~jfg&i4QKcJ(5KAz4mHf)ac7i7bh)!P||^Zz#X=1+d!)|qdnV#}f= zo1!F&YqOiHxcA=8ZZ>;ilWgvrwn&bWvg0_h9nZDL@xrZFZX&gLNixYeH+QBcx%Y?p zBk$)q4{*NdZ_}<+p-_17;sp-y0?#=(01o2#SeC*bTBB1Uj~_W(k(B2v2aNLtIcq7< z4_NW7^&ZHvZZ0)-EWes*3g_!54yf)8kdn*e`)?Z;Z)#sW$4G+XkLtv z?-?0W2GehJtz`w}`peZWTo{P(Ta#f*@I|oymwQOmy2byNo=i#8DI7Ij-<~RZeN2%q zh@=;Bav5#s*UrAR>H6*ycjgcN0y7Ah9k@C6^u6)b>tkz|xIRD&0o;PY<&rCBxLICG zW9xa?M)L3+h9hJo1OSgEqVRfrvM+>_dK*xESNbgDA&!k+dxnHew<8zfP+VNDdBY$e z4d+IZ_qa1q=a?;MvmXCJumm*8|8>^j#AX2w+ed<>MB|JKJu57A5sClhF)#$ol)yPt zPpU={d@jl>XGt}PtBK!&f8sysyXw**Y~5BU)uMG>5cDFX5-yeI$~i@VIX?&hB)07G~|aan#66z8zxJKSGTd#Ih5I* zXo_&JPH*QGt6hIOzm+rZeSd$3ouWf)m?L|44~94rGx4X=Q7UJ+kpa)jq)rS!T0DeVe)*6p48q#|%addB2eW)K-q z08CD?oJj|zpul0<%*jt#9Vkl!R0pW1L_10NF%5xQ0>*y|b+#7o1^6{*(?ik3WHLwc z2>~+XCbEeyZjL{{#jz}OZqg|+NqHipa7>hN2m7mSJJiK#EH zUHPX^ZvFmy@BZK4hYNi2|NZ2{|NTSmd7S;~-TB{sF!#F;5b68BxN`XUJQjP{EPC$0 ze|Y=<`Qeq{|MjJR`OevY{PW4L-s7ae5sZqV{I3~Udy{vu^Gh&AVzja#JwF~S0w%!Bg@44U4R4iHA2&tXvrQ-PM!#&i?6@ZQoef!FYV*!rnI*_OZ!RjG&G$2Xctz z@NWZ*GCwlR?ToYn1dS;TIs|Ote_#=hKpBoH2H$#&x4sAII$TN|`=j`8h|u_L=#Sz$ z0=WwkzA?cU@;8!aZ0R?b0WlIrYGpg}KQVsW<&$~WSDB!ctF1nAluiXrXEumoN`6DX zQbKKo{oJBS&aSWV-x<2mEdN{EX5~`HuL$oV1j5!n)fRU3yYYYh)Ja8KX&=(KtClq- z(A8po#V0IhkTVVzkVT8m^-bXn@%^D&n@9Q#ZRPF({RFaSIx(UPPV6QoEGC0YC_2At z%F=8i%W{Ai96gg{W&t|648ij|Su9{JX6s)Z@A>K2fjg(!AcXbx(I>a39^M#vbfJHl zZKB*GAa#8l2ZII3d=QQpIrD;5*$x8#)9D677Kqm{)KGlPuh_$PMnXLIfk{uhA6(B9T7g&J#0-q!NTmA=}y&_=96$r;d zs#%5$0!t0iiLRh7>7|peTWFvyk(^{IB6x?sjRk0Nfy!lCF4h*|_$-bL&8^HzNU4}O zJ79KTnw`EakuZ@sW>sf@_tB+)`YwC#F+eQ@#-27tQ(=5eH=c@SwFCFKtxm9c$?ML1 zNINi7;1C~|kzvCJ2_GN(MdkbVvmkH<2ckw5Ej_UOyEIg~s|8Ak*( z-f;nC0>C=DH9TwBA0|91eMKjK?hGkcBRX&<3w1sozezbGS7LMIpFU}X2C>>Gs7(D* z#XzahP3H#OE5(IA$7DFAIa*dEk;my>FZ(HKnn)-qL{@}XwhjIZDospGB0BXA8vMDc zQ$L}hGORjQ*I@zCr0bH^Z#mFs<%~*<`NcZ=gF=HaMUX>D94Oi$Y<;6;-O1By*#!7d zLOjaWVh^)x?WGkw}q-`A9o>FoJ{ibq}=%sPyV_=02bh7 zrup4(UD_vUL88%4R)@LdZud`z58XN4zjkTx=?8<4-y3{%eE@|I65#UK(dARIL1<3q zgJNmeNDfv=5hRll3+Re*K6xa21?&-x%jL~J0DqQ`8z=mi{y)|XfUsu=?%Xi zza0`g?7(unkz5>#Phv9Sa$yR%#B=A?mO?UPyTQM%AjGLLRudqJMFcpMj#jBGR)NK{ z;>cBU98*h`u{(PE-@gCR|N6;a{GVSe{Oc!J<`)lg1>=B&3~popnMHw>)3gaihY3EN zutWc&L)lN~SoYO*VBDhh={z9M+A9Y3_r+NNrVj@mu^uhM3z+3$gAkAG6xH#8$E?gw z^C%n64^LsbXV>ybb)%?v0QtRf!i&$nS0Cg@;g65?{@u$(_-7(e-2EW{ABU*VdM=o+ zRoz8h)PlkvRS%PbJ$HwXEKYL6-LOm=E^tBt*q`QX@{?=FR_6OZTYxcPr5WVMXC)Wq z1}k)&i;-K{#qzF=fO$yb=lJb{0=4^cff-Pf6cUI+%lyT~wK)@38l!=?n#3jMIz$|(*g?w>Q`?-|u%AETtJm=H1ld4!($-7sD;`2WL5*ML>h`+^dIp{ZY?7SUQB!;JAR5t z@(-$yNtNO&Ne<9l%;rj%w-vXok;@5SFgsP>DU-Pr{BN30b*Z%zZpQ+X#rUq}22#>Q zYNe*p3IT!tPH*rpY0^kkoolE@mF6rr18BO~>b&_BOtLO~RM)=41$4O>EFe~dxf)*PBfJ*SQU1sA zA1?><%5RZcQA8v8!#HrUz0lXq#HM#|`;SeJ27ln)EPzLt0uuqDZa_E4jQr1AN%gU* zl2?SqN`fh%;YqAckpDx0glh*3?|g2j9W^Z4rWz;W!CU7hJa4o&sn5x>NZ>TQDsStN zWY#h`FYFZ!D#(g0$ZU>geGZa5Tp;lu^2h-;!BvtU{l|~L_kVuH!K;h^{4wh(EI??g z!qzD+1&BjoEV9r1<9oONu`hYnu{wH`^O1J3Kd#n9@5{C2GN!b&1fE^s-;ZCt2* z*v2WhJO=)6M1JGH1^$42ZfS|jdGC#4v9s^~X}0ly(*u*GS|saHF787DS+RE;Qd7VeCh;GR0U&HkGQBgJ4BN z(&)WQMFQS|h^$4H+m_;bwZ1>k#2Khm75t~-ZiJeDfijxKuBH!mS%DEyN?hf0SELqE z8k}}Z7nzq9Ysn^@IGimXt)$af>B^6GHwd7nreMC6cn**i1c;J47Zd)YgsFVl z02+wY39_@>w#;k62;*1SIsY&7Z*X30?@vdL+?noQx;(gcW90Ge@uxQiADut4G{LDc zT`|9?i^hCp0A9dy09GS5@&dL4!3DG&oE#xG#%phUSTkdFplpDQLsCUe?Th9?sx@vI zkl}iv7UqM{e#HJ9px)d;e8K7?CJrI-vfOzD7El)yz%-!Pz-~X0xebuMO+#23r*P&1 zZDNN3YRG^93+;*Xylulg8u^(W;8aSTIDq_iq-Q$gi(sfGfY0VqBCXO-{4Y5?<_N>= z)!+Z+xBuh6-u(S{&wPp9whQ3D!QWhf185ij?UNh-{?{1oL}*7)2i4&v4b)Piw!UZqlF=*^}EsyS5(*iDl&t@K7v(6P= zi>C>TFRU;T7$q57eV78E2->$c8~Cr2ze4y2qdOPJr2l`=am0I9XQ+C#!^gIoG1`W$ z{kRNl|Lyxbrpa0a;Ya_q8!X5^0X?f#(ADj7KyDTHd?DOF)Btj13 zNXR_D`;7(Nny2wwg)0V#2SrR1N|?yN#tkxI$W-LU=LVk~_&^6?M!LRjGWP)F69*DE zl(MeJ5okf9&C^0V6LZbYt4!;HoF|y+&8XzB1H~2mNmFneE`VUHC4*ut$Yt@la;QA6 zq_^f|gAX6ED|rSbEj^~0+!E`^Jle1VeixM0IgX)K#Md21Q4!JRUtoNDVUxNFyuumq zO@``HLEAYSU=wonSa9fxqBC95YNsua)Z|V&N_j@Ndp&{(pxrP z?s?-{-{xyQ-@3XxHaYijp%_iKX>N~hxYqg+#|L)5d3N_p7q@Nw;wCtdU4p76P8L_0`{WcfCYeBngYZ!G00iY7sR{(^d_aT8U!}#ntc!{ z91fQtUlP>KpZ-vMA>i8j6Z>pB!hxmfKwTy&tV(N=5`4iE1d1?dr=Q^OfU5JDOP0qu z4Kej4yLzs1$uGd$%VYrseoQVB|EUG}^uih*PM&&p>GD5)%r;JT?2LVR0fiW=y;dSw zy@Oe~@#i-|OLX-t&SHLt&uK{=zCeegE7Y|WpN*ZY+oGu9#1?xvu`Dt0^eX1}cf$hK zhMD-qea>ile^LLN0T{^UU ze&W~fBbj{T*48cO_HjAmE0=e(K|SliX4xgSrf03TOm|KOb{BPV1dno|6Q;H`U%)|u1B^V+M(z0AHshPaHb?JdV4iF zP{`X|w1=mvzEz4L!uT)rK*rWWUI!DZ_5-X?{!yu{xMQ4Np9FxI-E{dK@b|ekxI=}< ze3k8^tXx)z!D4L{107$>Ei(dYVdUo@@guZG6EG+MZ&7vG(lRa!pB6T&_3w5&yIivj^_D2t2;35x?cCNh!+a%XUH282E{AXu z8S2-=WiI56Z`!Dw-$I6+|CeZEO(FWE2}m;3ZqbqKlS#?Py-RJV^KqVcaEaKKtG%yZ z*@J@@peA+gDA)bO|Bf8s7vEZtSk?R8{=+{zbMTi_=vujYW9;d>%mv0CE)1^B4y?r< z(WNuY&~@o>TsqIeVWtDD5raH9&iJ54#-VUP=0^*J@Xvapl|}fl2DktxTLCWF90)Ks zih@^w6(YSB965g!7DT1%Mx|d>8Gs=w5o!L>|HQs`rCioNd1per6OhKraO1y`-#h|r zG~mC`2Z0L+SJjP99H0n_EkHKlpe2Sz7i7RUi*cUdJdte9DMdt9Fcjj6ft7H2cjz=NIN9V=PMIHhAxFqIIcVJ`PsqGX*!HTv+>3=5t)p`;4@l%O#N`uR{Akk zN$UDSG!#n=Gsx%KuEQxUH6UAqrqJ^ozyh<*>gtL{G(zCKPG)g*mjhW(=1}_x>O@rBhpa_T1Ak zu6GtE58a&@T0KAU^v3k_+vmRg=+tMoj<23Ov^;bAckds)Klk-(I~YfAp||uP3gpRA zvn~+OnsDcU21@{i2PRpS!ANA_PZ4*Keglg%?gC)bCkL?rZBW!cOu>QE0kkK)ecSi|pzO zy1oLyGHWOm7b@0$L1h zy{rqrdZp*J8@pe9ch9cx4;=d0q?a z6=T{ps?(k98hvMFhLfJM;vRXh!oxC@xew$`SY4mc9n2mB@KuZ#ollIJ-BCY&z|z6ksh z^-=z;OrR0kwKUEqe-PeVI^+6vkYC_$$1Cgk_uU)oyFa?~PCte^S>Ba>{(D2(sPZ zcoh4nE=1oD$aAB63B-zIOSUWSY*j9B)GQtPEns5jI=0y2T9_E)ZSe!x*AW>k0Pr{R z7yNIK--+ACY4JaQ1SGkU2|$U!JkZsQOv&O;K}NEe(nP_jU89YD$;!JTCGB^g*DLaN zs9aPie>}Uyiv($~G$>qWO@d7FT(D{A)NAAVb<~AY5`OiA8eS|Kn6lM#){&JSqlog$ zB8_?}zm@LM{*iUz+Kn@R6P7)y&=3Tu14Ns97Jzw^=&0KLo5f{51W3=h_}4G(<10R4 z9{tMs?OSg2zIA)wo}Z8I`pFR1 zuh|;Od21NYWCh!e-nun-7Kc2ac|tG>d~+^}BOm4kOgE^DiO0_Xk<^`rl8gI-(f=dl zb1wt(Jgd4|3s@Tm*jc?rp5M=T-q^+?X@6xLNY|>apk8}*FtZTS{wTVAUg1lh6B{^X z(tk;7yH@+Rn|Z2+XLQH?5ip-EooTuu%ry+`zc+gH{^ql5@8+&|( zy94Ha`)8-0e=xLi{pjKXoM_;mFYfuPflXI-Zo0JV&Fgy^DV&F8-x{mE*>8oVF&0Yy zufieyA7~PiG+J~X6^Y1H2d2LYK-O66O6(EWLY&7}mc>Xh5J{aISmc1jPFB|H*e5+j zFl)dOh~hMZa9F;n%|$(Hf$$-|5}buPV87&6(ZKZJ8(lr>jec%1*TwbPSXq@7S(zTS zl}W1l|7;Kk@SP#)i;Le;!6f#s2j-KlfhAcIL=xkI$VWP;tTo|=skQZW&Z<#^{8ngG zwMMykQ3(R{)`36B4|C@R;igxpnzcVT+w}RHrn8j0zNa~|^Q!U}GS7x``_vhqI^O1@ z+hKi52v1G3aa(b{&GLb=|4e=0+I&$7Ggl zieBtx5e@TAXoT1-wE5bOo!>dK`|k$({(fTL-%ns!`sC`>lPHBA-57gxb!c^gd*_d% zyj__ZTsz&**2JZW!^@f-pb_FY0Qk>b;2?&DS7+HE{d4cfXn{#4WHYWuw{)3bMN&Gjk<9n}W!nLJnXz0Wk;j46= zA9e-6?an9W6!D4UNsPiD+6?Bxb2vo+J4$$5LFwh;Ju7m$bRe!x%vU5RE|zrJ*aPgN z=g~f&N7LBV;Y1a9jt-x--CZlg$nC7>N_!u2J{%$7U8}b^#QWT(??64brQQ1_CRTDg z`+3mt*Ug*+Di@I5o}KpxxR49S^6s9cey-&@aDNO@0oXtF^vdM38#AB1JM-&LCZ4{J zHIjYzXHR~46|(z&cyi0-ZEs@OoC~!t^?d_dJ(u<)lWaM=dwa~g869@&t~j5RsgVgR z9y?v*owwow!3Y>88U=NT5fC6Wk8RjvmU1anqt%Ln^*UbAL-^mA?#Y3iLlO{3`perF z6)H+LaI5YQD}ZzjVaPMs67M45K8B;VMh+8ilGbGc2&8@~5#A(4`}nP(CR`F0jZ==! znIZDZIqOd~Y_ZT2uv}Id0RPyupG8AqNrq@0pBw)}n(bK+{b*gBV#D729cNILx(G4;%yU@9nt{DB6+}eU1hQjEg zA1Tk59p8NvIWr~?4 zS56SKnbTWaBZkZo-39m@a0_u=#t5R-NbIo*XB-_48}+r%=LxDF zj$fgok@ODu%2n#vWH)9L!=L>K2B*Zv2^RRTKXixUrV|H^6|E8=^>`<=i${o z?c_(v<9irc*wwC{`@@IsPVRj$#=SFGjy?V4*4(o{g?_$a6aX@I*?}2WjD;M4#{V3c9wzwo{2aEKxcx9A z>nM)lQ1M?tR9S!l-*A`U?=h%Ssz3{cuqrATPGs}gAv@?v^87h(?b_TN{!jXpj&dfe z-&H9dL4z)q)aIN7BpFE|ttVGSO}-*c{*LlfV1!&h!D^(>%B@}PUqgR8cWik|x6j8!fJ4N{`B;Fo^C?jb1>}t$zSjvKAr{${2?9=5 zXaIla2t>+`y|f(62w)0Fblr&r`yxWem0m!!X9@}a4mgs@f*%PKj!<>@$p{<(&pR;{ z|0zzN2l#t^7I4OCa#0mNep|RhEaQ^0aEF+@m;jXj2=h4E{8=0CT^Yq$QIoKrF)#&8 zI>@TS6J48*Nd(Xy%*Pp-6Uhm%EfWbJtv(C8umH3@(&|LY9f9gX`#^qwTYYWyG*hTC zmic{js~+7={3j4$BfsT*{5^Ns(j$Ri8veT@2>h%Ku|weG^7)~ai_@QdF!!5}PXGE{ z?j1h1a{lPzxzYcA^Uc3H{LT68TW5Q>%m|aM=YNU&j2Lm}dfqtS%T6BRH=XbK+C29& zc5s-EomiTkoRkGys_vpQx`Og(aISoi7RW|$?Xqeu{Ss$Q6MAQ57=3wUGudGgg zw%Hj)r8r5A+jM^Gt8;I^j_K($*qz?1NSOGAU4L?6%l5xI(SLvb@SWKMceq*RQvc)Y z{cG1Sz|KVj18e88CV@>k7y+jS&Up+5D2H~1`50;l zvERsV%m?-Xd>mHV4n3G)xA4i;vs}eE`t&k3i{`%k==92M?6w_VnwkEG_xpZ0_Kn#c zFHdgY6oz`fKDV76+S(eYdjof%d!&ET73q-3Z!b-5WyrAOIst)X?(q1Q{oKhljx76C z{P$z_cK7-JjGrG8C?hm5L9mc=Z$N~GPmM_w1wdSikfgEzVOJw?f!%kqP2dP`D*dhE&#bjO+MXNa9 z_*3yep;G;-X;K5Dkh2II{x!l?w|}w!R%bCufHG;cTaZ!IT)_@<>uIJ}zpYK${)@Ka zv@mqqxhYyd+JBvB;YyhWh}tR|QK%a{eOFVwtj<~7ZknCV^n7b}&zm!ST!pML$atLD zPItnZI)4YV>YN?ew6J6I`+YmUe*$AH7!*3Te0Ff{Iun7>$Ja(5T^?MWmx*cLI0Fla z69g~otw>Zz%^(LcW^RK2awwh&fqOa24Dy91v3<{ z-ja+Xw`L-w!AY10`K_W^9s-t$>Eliov_l*;UK!cHgjFB3Lu}fKZ9K7_o17v8$p}mU z8X=v@YFK~)ex}C7t2Ii-;p5L&~l5WcU27hnhf9L)w4hb^#Lm7DL`L(If zZcRPEJ@xFp;fGfaES@>`{M?>jjO_l-Ne1JqlRLP6S4(oIcfK*#C)w;=&!*^^TjqLr z~L8D!tl6z{5n?+YVkNnSgHm?CKfFq1OiT ztpnv1m&J#KM&^m?nbK*RNA2**WW42-xr0bu5B`b&C0={Bwe+TKc#+b;%h1NPgPm|& zL|X;MW^sXdWdk`_6wue@Zw~!Wi~q`*vZ8eSivLCXp(Xe**OOpns`5t!ostYoycKjo zJZTbL3&PiliJIsSAh{dX|2In^U_Pt8@${uQH0P$qSM{Ur*%Yp|@U1dp=yW^N)M|5f z~WNuR3 zj9G35%mq4+!LRvQIBT)|%K5Z|B8n^XQ>yG*Q#$e4Zmy2~(vqIVgs*D4d6^f?ZRbOH z0Y8*5$MCm*a%}&PC$`-g?zwXc%X0mzS2&J@8L`2YbHmFQj;&1KSQkJ<L0hYe%-sldg;WM+7DS#beI;144>U0c~lV5QjQ<3h*75R-49tCAU znLz|@i0L$)Ip-IqN29xz;tf22o`(`6g)~Vg;o_?JWb|;dNLjS3F)B4f_fR#u@@RoM zQ8xn|YW75)@t!k!)vZ>pg9dTdwaCd~5I*ZO~bTkhXTF&A$F-RdZ#)bawd$|6~FB zUzJ}Q{FB-)iKsS6>5VjI#sAWQ3))wB?>shblHku_Yph2#SC-{Fd!Q)E{J#7x0H8Amp=Y z2e<2Pf7SDFTvzVUFHar3Ke>N#g3bJ_^$)MkPdvOn_4tF+U%of_{Jj&a7cu_1eP!&_ zzr5G`gHaTQU%$BZl`A`6n%hbb+;YB;KEu%1G>bl8V_cx>;Td{YV%$;fGkiMzaAVI5 zcF;*sMXZu%ogn0haOR{J4RuzoB|>wSz($ZCN8k4B9xjmVsf)IjPLg%Vi1DJ4QaOdI z*)^^WkIlMp_v%1`zXyA=fEEwU;|iy%C|43x^%SMIl#7_UFx_UAKN6L6`4?I_D|G;UrZkO`MIM@w~sB|7)+yQU&h&vD@0?v) z9>d3ZPmuzFs9k8!qfz~Z@hPH%z=m|=Kk+z!f_QHvCxM;0013<>jP1sG@VSHDp*~9d z2mH+%xNi&RSp!+=lThy)+w=1TaL4#DS%4Raty#*HMXIlM_^sFn3a&gBm2Ru{bM_~Hn)Z2-(-Ouao$%g_kLLK)yyM$I1UKnGwA;B}nlfTe%Z zd)31moh<_dq|MQx?j2Yy+^9LI8_yMZF;(UQ&W&&mia!|Gfd4|LU{B5js;He^I{+09 zgz@nA7!SYDOnlcXe@KeC{u>IKdPlo{}f<{tMb>*>_UH7IC$l={xwPy+zsDEl8H3-0j=4* znX}T=|J!yj!kSmsX@~n=z2$)~IL`oAmEoHPi4jMT|XnO22x0wjYxwMLca zy8;sR*S{q#cL&g^9h7K6_A z&2xKRIp6#BnYX!d8?J#F_LtA?e&dsOcK@uO4V?S#PqNwj*xI!dYuCUHY}$-Io*P)z zGVzI}X%xuEmg7J%XNoZk5ZgWvERO>_I8;3#Kd?^>68_#L%??;E_CBKCr3sMV&iKF1 zuX1&wJvkKo4~h1|CNdLMNVM#PMoF6 z^vN1jigxc5C-6t?kJSNzyaVAUq;CwsCY+Cbf0bf?1egVAA|MGroK|uX`0vSSb7@#$ zW+fMgi3VDD*PS7@Zt4K@Q_a1H;_&t`T z&%XUvN9m1koYhM1EAwx2c!aI{+s^N0^8olCFe2le1n7YbgmmhVF~HS7YfsCrn1QZ7 z>CRd3zv=;$Lv(KqjjF^}fB_h+r_H34MbYce7nq)c%|cBO2co!OxhCY-3clx@g;0S#a7wM1ImqACQvR=maj*ZCDK>L~Bq;-G z@cPRLbWpV7f2I^B*J~M}q19bc5=v2wx-Q?v{RiD!Y>p1S5foLY@;)cd%b!6pn-SrhEwwag!`RnH< zWdIsj!goy0SsWlzO=N9DBb#j;p&pf@%2Hpfu^K31S%Jlc;v7i}fD-AlL2?a3fmmoT zn2@dI*sl6g**}E;Z97;F#8-`y$fibaWR>zq@juiWsW_4xPAO`-!2cru2glc|%s*yQ zJ}Tn&p%n3vR-$fpwDRA9ucV)>8dosWZ_ED;0>FPw9-{+jMpLWl2J8?M@kGi3Kdx>! zf*q8UQF@d}S)F{6a(&x4$K!W6Nb~{!FX+)yNX%-Bzkd4Zs!`vzL{pnNw}G}IZL*9< zqGQzaLpROuWTvlC9Ala30E@z$7sHy|H_mT+8KytC`>naYmpRUf&GvJ;ci{Dfo!kHX zo!$S};O<|IAG$Ypc=7D;r`NcYYUJ6~lMgQpJid5*^}-3POtW`%ankN6CM%aGS#3PH zC^G_BkMY6*i~vb>@A4Q9RFB19wuT16S4~l}fHq*17Eq%gs%Owh03Ruz^J;mtkF`$x zUu#%3P-z?n{X-1>B0pR8o_RTx|$~bRe=Pi#N zVZI_i$FGtL*yLtOzcdK!Th8}lF6+5_?+;>}2Wek6*|5O;V4OW#+y{+KKh|wIs5|!b z8V1?8GHl>eT^WX9SoUQdeSE&>M`H}MZS%c5&hC4CX3y8p?0kKym!%(u#!J&%xp;zZ z@Y2+d&2xKEt-$^1BuM^tGDyWP!LUh{_)kX){4b~DvzvL4YMfTRjYeMxHXXmBF@2jp z$+sFNOs)fD5(9~3uqeK>`JreDI>iAORbUIXYEh&>Kpi_8LBN8kP4r*@wl0_d9Jwyp zdLH5GP`k*pK#=MiXx92fO2i7yhUyaF(18ECQ&F)RxDNbDzcI05ybK!rQSA^Mwyg^> zSuP2T5}g*?z>!rK+{Tn4?mFJY^J|hNS>r7t&Dx+OTEMLhJ!+`xki(%$tyE#wUv>H9 z)~z;4_>KIX`MQ>`iX-EyTSH|9a~A>8_Y_lq1ckafU8OtTcGU_G%F^rVjPr*Kx)a@U zV-Ai{HQgoJR*h+qX`^vE?c?*#9igIhcnEI#usU!K7So@N-;%*FZyyOm49>H7f8rRp z0K{+)kw;?U0~4*%-R zkq7g~moJS!e}DMtdt=Y9jeUA$VQUCpz+Hg{xeQU0 zf^nY|CcvX(yk1~PUyuLd5p9ga<|C0__-_ZK1N8yy`l@mnMFRLO3(%vFbghgq1t@M= zivooUL;_>G@tiPnK5rBMjroT0HcX5m9p8x){|We&j^8eg;0Ww_z||^pB`bx8%gNjj z@&SAna}PZ@9Xs~th8|yF$39!OCZ2QM@cRRgZ=QT~?dZw^$Gs=Ny1n~n!))Mx?c82W zF|+8;TF13E_PF;`W~sLvdm{>+{KWa{_h0=y=)F^n>a)IjxBp z{P8#7zdnrr>vH|$%ycS+r6;sBFf^>E%}5jQO33qMC_Yk74SS!JF0X%WZih|{^DD&& zcCyKqd}5UCLMg=R0AIOnQ5L}txWAjt;afi0f9Mwz`+jw5-<^r$OBXp!Jo@z3 zuoCW71eSqrDg33?>3}~8c+}h2|JkwtBewZM@vTP+-*53#dM5x2fbaBSPJeL(yFJEs zKsy5la3DRMUxE3_0*wDc_(i~fgaA$_b0c6MX@CFyF^*_)D387R9M&Fwd=bo_e8!Ib z8>gS&ht~#IuV7O9Ys$aFh26_IxD^C)OomI)XEhSTS1*8hD zTj({+ff~!n>-mMS#cOI!ywJEhSGEOG@Dt}jN}3e}&)mBeL0DkpHQ4T(JgJBE_~!O>0A`+wfMD*tJbsZGcOdiH3Dzr#B^;bH1Vl z_|c*#ez(bXxvoW4P?77!iLOVQ#lKYpq3CdGQ#0K7S#@S){>T`yzK-<%JL%WYOMOjt z$8UP6|6u2p|0Xq}I#rIM?j&fbjr>dI*^-_SY&3=K%vCim^0?Cb+NB<@cG`Tccl!s2 zkv98&aSDg&(c{Y(urWPyG1)Dx7d*T&^6*ms(%FHfS#2o2&zaM477ox0u~N*I z6%HjGTRn9I{l*diJ`NswIv~Rli^GR>eW5n$8$~%?1w3-NfWuZ|87rDf*n#u#1(ZVQ zbL_ZlQVF=OB@PalDFk{;>b8(CzOX!O=P7`foAF6$sD~uBS?V~|;s|c<(h!;=a9)fi z1bFZq)&OEtogH@v;0p$G=;4ywT`Snt=ZIFn_{f9dZFdJ0c~92$p{?iM$=>CGzLi0g zJR#(30foaC0RG6M3*&6v`Sj-5&p(`ec#|VqnDV1NPhfTbflT(vF89MTy&s=sWTD4! zhoL8fpZqEQHGoihkv4smz9-lZryf{`szz>zb9}|W_DJ!7HF$RSu1My{99Al^&dS}> zoaYPu+P%ww+L*s7A>LUjz%|+Q=SJ6>Mf0{jA*J44wL_jAm`%vX_-8m;DGQ}n+Y#eD zGiR5MZ*<-0GreL@T{**5+t#OIvo(zQ_Fbqsi`qY?OZYk`6^jcRwiUw(w1d&8TX3F2 z^Zz!?)IcivxmhoOepsjLVyXgXV&}|y{BMgc%^0)4Y<3cmk10uD?7~Sux+}Kr*@jIF zewJty3PH33v((Y01eZ+k?;OzZpH;1ESLw<*8^k?Xm1>$-i9?>JRpIGvjR^CDUfjsF zJu|B;v<>(#I|oY<5{jBZ$E)ll{xI<$svJWRZM&5c1OJt#CdGh$ttK*Na4L+D3UOszr@eE7JTra}efuj#5m@K@5qT|6h zqAzF7KvWQzvr8}wq+D!Jv!)DRKrxb9BNzc&U&ImWz9R>UHYrvXs%FW0p|PU&NtIEP z#&eA_<5(FKEH4lAG!8K5a~-on_+N^dOQ^HpO5UYogAy#-YC-wI5c~xhe&3zZ1NX-F z-Q_ga;C>A6+#T4D$;}m3RrYDe|Z<91#5Wa5QI0sa6!PGP(C z{V@Aa_Leq~oxzbjI`D#?8G|d+XCQNP3>^=*uK(BW>I6cVCM&{pQFl}VI2WC1l%RH0 z-WL3C^e2S{RKAduThjL1gow;M=`Ul=L{^1^pm?ra2WccXS1pZSxnbgek;i~*poWQ9 zD-Bv<0_KE}>3U`DAj6PbhHVEG%S_5CA=?!<_;2LhZY6xBj206~4TfYsB;a%97H!xz zIK)7P>uCQ4kF|$5!`AOKX=OX@GpXuoR19$)^mnZ8ZXcF`&+MUBA9ti z;Tvb){?q9A$m#^ko$s*WhsA>B(Zh?=hwe{df0F%;Fa>l(Nb*b; z5T0etCRPwoA~{T;#qds8i^Xy&_FMO^i9qO=l3z5RXiXW1CdXPGd_?^n_xd#%feVD$ zWcJ~(8;5eCjZ;@50~+oQ9=JPnWNG5S-I3k*`+Jv$w90&M;3%fEm&Ok-jtxAVqT<+J zl6C#(w91~2e0hsw7u=#duyowQ-)jj`Z z?oE#GNnaNOkY4)o>^9IoJ8=1}^knbBsK!;wHarB>5OUPjYY+GM%1+|Ix~>u(m_Fc0 zcZ^J*<1YGYXBf8e>P|XBTlQ2qhwNI^#ja4I@hH}S_>|B@4s?D2dmYOj4oL>IIjpi8 z;L7w4_^S?@)!cYnR}(r!n$E7K=z1)2X(KwC@@y_J%~+uitxyv9*G)3{gJL?y-${IM zdKc#gA!q+Se7BVoLnpOPxNae_(>~3#!ihE5+20k7toGk90Zi~$;{+h6pjw5lE|i32 z#j|J!vfT>hwL4`z0lp=1cZ~5l{x4*>4@4bhV!Hinyj6l`wYvTL?mteGv{6>JsyR3V zhrgo<-THFr*}7 zn(Wy!$;Gc)T;LMemo9AI`tdtkK6&Tuzdn9^alZEsmdDPpafn6a!H3ttH`u`hOySwB zGhe*VRRsVbdXM3y^QRtN9C$E$92*pir%pVYVfodxek^PH9hgL?>4q@ehN7j__ zaVU#$=ww=#>Y#vVP+Cs+TUAFsI6iN`BFwa+bxcNj?v3Cml(%fc$LFiVtTG4YbM{K? z>A`s4onh=|9OW7pu2Wf^I=(zJ{6s6`Xzz#DE}mwIgmbvh-UslJ@Ug=%`uxW5r&ms_ zoj-Vg>d@lU*jLxz{_%-ze{+2I_XfT`zZJCxoAcj3*T>Q=eNu_%jq!=0&t&h? zc(2kIm6G&TxsvD0ymc2PbLZ^)q)I7uV``E?veHq_0xCVm1Q(r&MaFupNDk#{X2p@c zJ(P%VKUWSLgxIbG1_vdJSwkGaEa1OR{*Q`N-!?V`OH6>R>36yA zc*=Z3Gdjk|#t82Onaml&%99wr_1mt$+4(U3WBb4I zRr_t%=blkQkAJJkb6=X<%}FBmkYfbwl{4Ex8z0qwb#4#4O8CnpL(Jf=kj zbG_T%J^JP+N8bFK<0D^O+k00Xa%Y~uKmF{zsn6fzFdg={hn`)3XXX5f2WO8i&vKp0(|M9>J`$PHf>*Wn1Nlb6la0{21-v<0j!?X4u)0~hZR0&t$#VYaW zLN({k@Nu8_xFACl01Y`7G689_$7YpDFKu%(V3kSORNtryHXyi~S&-`6lSXX*#maoJrQYLcDpj*DSo1G5K}m@66Q>wHp{S-7;f)iL^mlVye(FlQ7!4gQ<21)Y+sab)<%o&UAl-*xY*coHTs zYz&OMWuS*z%XyI2$(jpI;(2Rfz{!Z$=aolv^*7hi_y25c%U>MiT2a*Xa-w$d(K+1Ee0b*b+cVE@&wuqHTcJ*U{w~Ip23Ic~Sv$)m>BraR(PBXxENu7R_4oYf1NVEtzE3b z`!Bnn5Y~2r__ON6c2$ybZ*hO_?iK3?yYs~V*V*qQj27`2tzYh@W8 zs+6VTLdW9t!p6!|{I&vV%vS2nm`+o4RxSO6>#Wm_L%AwF5UKt3{H&x(1W;w8N3DKV z=Y;{+(S9aSudDeew_u~nxqxT6W2Jl*xEFQoY;_Ho0+I$Af)q7u`*|B97eZ^b+k(Z|5{QB9q z5C84t?ms`-^W&knzkdvE$vbzauv~rc-s!$yjsvFyinU%h|k*B{LM`U6suz=_jm(joW7`>mV)@&mic z&u&r5@beqokixBMEYz}M+rM;qKbN*IX*$3~T7yq7p8DOpZ~f>P*7J7$V4(lr`9E2B z^R?@t(8JEge9zYTUM5Y_=bZ1OgK={TO{ATcvdXJ|i?omJHGc6XhS*sh)0P@J#v|>? zzwj>r9AL7f7vNlyyoWPl7$x{k>ftF>)~;gkq)=s5k)$io`D*>&&rh5nzv2-}$l3VZ z<*USS{wgz3bz&4V?mEJMaDf-&fAnzms0RF%Nn4SM`5Gn_!wGm0QJlt3)Y`<9aF9W- zh71emA|PEOFYy(ntFriU6Kf3lZv5x1ooK7$4mIgUZbC99$lqd)T+RgxLWy*x0;50% zIsR`;c~W9}vQ0>%I#zK#F^#%Mmk5goUiq!~Uy;8G(xDVe>ty8MrtrM7V_l(9*(vk& z_|N$fcLVi`_(7!)N1+ANf+e}@x@ze=v3E#jqyqK-Qb+x)>Re68AOVe*pQMZtptlbH z4XyMIeHB}Fa`9!+B5ZYv zq}otWSVl+mXHVIvzKRHj+Zk@nQh1d00{ka8X%C_^xKiX(sEulpGbD+s0DsBIeS)4z%bnYZKAj@6k1{@swRI4K_ z*S~g=1SeK59A7?<;}aa8lgT^xW|@*4yfcl{Ey<5&hJSl)`hR?|<%b7*e>Q}r&Fz1C z?9flA_k4GF69?!n?E2d5HZ~a&c>SyF5i%!Rqb{N>k8lLKP2^n0W9f2%oR-SUsH_O19M(Jc z2Y-mqV}|`mdZ%%>ae@sn*nz}91pew~?&l$WS;#chX#Ub{iKIsv5?yW*-07&%W8HJ; zHgq%f%mna?RC+~;UG)tb_=G~~)piB(%#12AmImDjIWD4cXb{QpINE_%=_rd5H7H{2 zXpDzW#*N0m;HRv=Em!!@=VtmEhOwL7BF`8a%&_J{ibL0GV%|JaHl-Go1Z@zy9C<#=JWCca4Al zU*X^X_BZcf{mtL}KfHhQt-o>pITaLLfjH{)$5b6X(F$toiK<$C5tmxJ!>Z=4zQ(S; zrtV0iqlT`qt@_SBQC&wbs%;O6YTAOL>#c!nE&i*`J?Ki4?@~h-x>(ktd{oB74qjJgm`tn+n71*-8_!M69iIhM2$xrw$ ze5IfM^rt`j+0WjR*Drqg)-Qhf^IyLGi?@IE_B-$X>fQI=dGCGn?)x90_dfXW{SQC- z;G>T}{P^5Q=gxn4{=$dnE`MW9WKB-;!t#+MtrkqhJVb#3RbHJ`iIC>VcyxkeZUV-B3b_~Q$L zu`mqAFzmwkXFvZ15{#k6g|To&DVQmfMeaQR*FO|2?M2&GVg*{bm6x7L$}kukl7D2l zgz6t4!-6q>*yW1x#x}`#;|ule7i(HC)HI*J-XtW8H^w20H&&9x8ykoG?uRaij879V z49q|K85qM)5v8BljM=uX;4+jwaiI_>FE(4%%K`SdC^%vMd(#ZpG+uFZwYCXet7{fr zuWzYoXcg5qwu$ex%RjRp?(7Vxey|MVjctZCs1R?g4*6nT`=z?pi?uC6G7kCNm0Bcm z1y@flqaU0vIAr6K-~aem?|p>CClgov@>lP0T`rLP)?1J!3=6S}sKQy9$z$yF>hJLP z^VjrxjSLe=l!+xyV;F#cm<$WacB$d9%Wwt2l^2_R5simkQL$^0P}vTTB}lg8WZ_vt z3mmfg3n+ee8t65(!H%tYI*buqzlQ9v1hj9vJs4QV%Q)E5>#VOeCx^um->w&Fwyw z#K3mw+t%r?Ag^FpoiK*Yt!=x|)kSU4xs0+f!*H`N+T@E0u{O6_V>k55lB{h#jV^4G zuQYavE;n>uX*l-D;*BZKU#$aXN*Xd8$`3xi2*!A0qGDQhH0!iYN3*V!QkzfPw%ux3 z4wbsHhLB0A?`jPO{J!hFiXgwE?{djNTsx56rjyp3H091+xOo2Jr3;rXpFr#cE5kO}%CIYIVLN1P@d?t`TYAv7X5ZDOZUoO)8#@pI2D(z$dbPgoYJJP)+9r7B zXySeeBnTm(_aA@u%b)zzwC0F}#lP7!if#Kwm#z3=C}TpPvZpla3iez2?t9kjednbW z0<)IFE$Il6Bqb(2}56T&{+@1%K-#AILmt@}a(| z3mqpS8at&%N_D(qc%j?U(IZlZPo-B@u>GxVcXx+WrSw*=Y4^veFy8*3-pYYx3GfE${-m0N6E3auC}ugjv+i_v;AY-sNaoGP1J+g5;$5lobo7s+J- z_Nr|4$6EbyVc12oYthR~yO6dQ1#EH4wQa#VGR$p(W3~G5#)QWoT&jKV+|{=~xcJsP zAO7@h6F(qGmLwY`o=v5Qs^LOT7g<5EEG1S}D5))T^0Le~5n6?|i0{{!Igao$xJrOgMcwi;AvBjrqYV8rZptXrr8+29TU2Swb zx`W8BvF+o4!44iy+GPQz(u?7aK)kHVVk``|_~RlQW|wWdW!qN&>}5bQU^mi%LZ?Yb zsHW9VTtP%ZlI`8|*M9lorMKQY|MPdxIr`}5@0xT3u>|q3$Sl759t_JxSrJv^n6s0X zu3&@8DzbQT-49$Gf}+0kEv>=$xa4)N_>#sNe7Z!v)F|W_wCUdc;5>ajr5bQM~R<~F}dK@~$;bs2440g>`4=xV9;F5}P1a9Ob10`ay$ zqBW3Ej4^~>t#QF@FII+G-c`1N8GtX+ z2eg=!ATSn;HIl@wDN$;;Xw*er0mH`6Wh;y>GK)x_(-p+fdfPbfye>E|V%@VykcQ#+ zKD;{g|xU6=Dg>cRsrO&Ijj75evQIjX@eD2pz?V zxrk!XX4SUsHErIgw-*IJN?E`3Ev?Zt#gKZjh2D$K%Ldp)yhZW-;Z}YNl^BBY#}}@A zc;T{iyBm_vU4-OwM9Fjww-|@q(Ar^|V{M%h&=$~b@vFZTT!rCdblU^19YG^IPAEEC zaFu!+;C2EACu~rR6<`dlbQ!V^#A4W`&)3`4(_1J*Nnbft%Wzq+sdO+l;Rin1E{Q#e zG)l|PKoa2Fd*Yzm+-ZV@maYg$cLh`Cbm%rnxA{z%%{pwMxx2Tft>6e;!?-gTwT3IAaE+;w7UCS6tWlX>RXm>+I?9^|W{SQFDvGwJq4*-q+sI z+twa3>ga9n>}zQYqNa{Ob7v5>bcIA6-F;Q5(-*EvT|E)hU9l_+FqN;1;RHT9}`RF2k z313u@85QHmM&-i!i^n=iq!8;Wbrn3N+GjMp@FO|)T4Ykh<-{JK{?fJU*Xru)n_F5s zI>ETBC*<=-J39MXTSJiC*%j`_d-$R-j9R<;TDyDOe0`|BCoHN8NLKFlM_;>odQ)ZP z#dcRHS(UsP_Npf}hjZp#{S;YKXcwCmnmT*0H+5gCZ6odQ!R6}!{Lxj@#Y_$j!LW?W zDwHf1bdAgCxyx73$0v_$DKM8VUPkh|bn<1hDwlXIPp)|SQt9VP4cXnYx_J3YRXTt9 zN?GBSeYZ@AH$oOG@DB%kjZjJZzN3l_7AgbL2w%eiMFDsnA>NYC=Q>-Fbr8W4G4y5xjp=}0XM z2_VnU*Z_taUcP?eYR!eK*UY{>s0{S`OihC{Z>`B7m$~)UMs88 z?^(G1en>@RMeW}+j ze_y&P`TEjTsq7E0P}vji=Uo99Lq1CkTr|PMWrjvvZ(+zKCF6XEB`(%AAtDMG7K|ZT zdQ=NT0vIC8*Z@Ov&BbfA7q4AMLNcZ4%z|o%=TaW7S}zM{Pt#icOlDb7Ut^{Gy3&$h zm_UMG4avA-O4gy~N^L`3D;>Ojfk-kGO9!K=V6;CF%Wzyo-5j8B26grIb991{%wJqy z00+YTWu?F6jD{ERUVrY7WcU+-HW1C?eyL%xmOf?2{lYLJijYy4X2e=;BTg7^48RQa zp)Uvm!NsF?wa!Isy}tH^b;%B zT)kdXmH2gKCBN4$&57*jqs!MWT(4^+K@d&FGlPApfu2a3V}W`c`65{r2dMWit+Jp} z>2-2JR8^|Ls@Hb-6ENmov(v);xZj5MAkd14BCa-cB1o1YmoO|+fMHlVRSQD`7z)eq z08w4z<+{eJMd5Y|x?X>!sB72j3#zHTURx)+R#RJ6LX?76cAW~9RRPJ$6*g7&tt&Mo zgv&_4w%?*gu23IdzWhFo)0&#P_O7nJXds>rCi;WPd@wN(i01?Gfk14?A06z84*FyH zP(0uFCUuq*g@5-k54_w;> z%+e24DC?T9JEE8BdPDQo22+Zz)i)JX+jy<0n%YKHZGD5NrmkM)0$VwR(zEIoH7U+v+2Yb^-p(Gj# z#)pwVHU!V1*uWcQ_$(Xu^0%RAwyZ#_thlCBB^)g4_az4rhIn0LMEgUDTyHY(3#S;j zBf}{vy>zvyO?ADoO(kOh3L^m;T5BDd#m1IvCq<2lMvY5#4UM)GX{ppj3?baEv2Er5 z)eI%M+CLXoOG}~GRbHvByHs=iLe2GywKa}vFV!~4HI9&&gVLKCLczo!^n!73Y8Zxl z69aM_F;F-)6zw08nzNVkx1}Y1zO3vu%Ys^=vMj(7u=kZF?~(>)7uK#&*qF>{5EA#zn6#;)kJE%1d>1Ff16e=UaSz9I{AeG@KkZ z5d}^-IfNZa7X-a$ht{>G&1AK<7p`7$h!>~|_1RZ+>OjJXf$4*9z;Ded~IC zLs?Z|8*dEKl-gJTV^Z#fYV>h%fTE741ziJhYJ^gRjrtNpCcsDxy%zPx2Txa(jmp=^ zFsGZ)E9Woa1SvJ*hnkjdi5xH(35*Az?N%OO2yf|7)i!siWQwAc4a^yL#A0nr`}LM~ zN|)-I+f?;UZDmyow$>=mUWOOs>ZmIlW%)cyWm$l!^kP`nFZk-3VuQD~fiTRZeXce# zB)g|CnaGZ$a^u7d&AKBM6UycfWHoXX4Jdd1RSZnj$gFY8O}#2HOA zLi3IO3w$rFGs1(K*3R0tE=p`_FiurnOQ-6@92w?$IiivkbUV5-hP}Sn@+XZg9jKwX zT_t$C7Nt^=KD(i@N@b%m;T7Jc1Fo#R*siT>Qqi!boqM&W0pSEl@{nUE@y`CCA0!gb zMbm?dF+{-|#ELgQBf7fU_hHzJ)iA+%IlUUIW&cXz2j0R1(|t_;MIria=>RjlD~&aQ zxxT}v;JFMqSJk(6sqFa$dS4DI8``?-+6%%~x#rZc*i=wwQ>&4{T((r6G0Hk{D!r&~ zXlg!-l<*3;mVK)%z!fSLVB5G}*F+~#O??X?870Yfl9Tl41;Ys#j;2Rr{bQ5>DJY6J zRzA;Scrol%Z~N!h#jpmnXEgA=tcm-jE1AI$(uG0jOZ*^|La#6kq79ur3aZNxAQeS5 z?D++HKN%_;+kKo7B5alXp-sNn&23#GAz68LEh^hK&$jKwwim#S%`GZ>9fkRfMr~tL zS(U|@v!K4NslK*Z)KJ$Vs;g_ce1(v_xv9CGlkxI3CPZH&I${@b_{bGU`X^%9sc?Fn zWJM@3(wiK8U1DoxCHXxm%Q{;sBgw(CIwPXTt7&ZSq|vlKo*g5QpaV`5XaFq1urMsF zVoSKI&a~SLMuo?EU z8=KmcRoiH4X|)#><1?bGtCa=VtJ3@x3_BP@EC5qB*0&Np@IA4w*EAshysoL4vw%h) zd3#2~;w@vj3A{0x3e=Y#Iib{;S)}xq7xQHSrqX8E_Q}{@u3PKNMg>$VoF|OLP$V^m z!pTwD0+$u8KC#RwN#M>8Z}o{9+Inm?w)<@{kX0m=x~KzO?HaKezun|a zOQccKdPa5n3v+Flxxj>la;3qZxj9lgHxp}Z?H0APbg8IOTa4!B&gPa5TX;E@S3PXo zQqC1}m!T`T4A*M9Sb(2AIXqisS?ozj($J&b?dwg1(}OhhV%ZUsuSg9QuCwvHKbCW{ zaDyb1(OKdOdmRPOWw^Mt7hP+XF1`Z8eeu!WIA4C0kjX?%sUaGM?SW`xXRsLbw$--L zg2UyumjY~~TS}~pRT-g8>8dX-nyIyC1=!)-p1I&$1K6?+K-k$E@eN*CC2{{)S|O#tIKXQ>feN@+8; zw05d&Zp&7h6&!}8JPXP8I=1aXR~HEqsuEL~=&Wa;AiYanBr8(6SpNWJq<;v3F$(vO z{8ccFcP%U62V(%1rYjj30B&RgGHo}f`Q|j)e2rZ_4V^wnhGEJGMbhAPVix!(FiZw6u;rEIshb*YqF3@YtK#k-}gUE~F`4Qd73%S%@UFe?MF z=@@b{^Q0(SyMv6_#2eG!%78Zl3`ka2j9Wg7@3q%CcAna>atxR6wHLkqY zJGzZSu4|?@pRvcr52psm9s@8K12ZB*rX6JSc^3N^yuTd7k;D-6qTXm8fE!xCHDe$&MZvj%S8x<(XK5F>lE{ z4ox~l&VsJ4^ClSf^tT?dM4TKr@jQ88f2@)F@HBPPYAZThpF?a9^osDtQq$b&SG9Bn zT;hV|C0Z7u_MYB9gY@Gt_(}vSOc+N(vdyziGPVUX_suhE?eN)ZY45hBY3jC)PNW#C zTXv!Q%8O^=T-RwJNz%&g*SJM|Go9=hcw;bT$SWOr457yrLvoDR7(a|>29o07iZdF2 zPKLQslvOf2MmGwR2MHnYz;!L%0E~mBLk%YkoE-X=Za-0k0hoxwq8HmmudIJ6z!2pH zFju;&!51&I`AFb@VD8B8Z+hAi19 z?s~*+H>3qrNV>Xi5hJ;*lU`SGwK=hEo263Q#HSsyv$#f%HFbVdj%>4 z;ifrhN$wvacXg0b9I}?STUMUiJG(>*vlzB#u7GqYzL(q^(++r=<>Z0V828#7FZJPao_7$-A>$^PMJ zB2VY9`dH-?6psNr*>=-)bcM3q+LgMdr{Tdc9@uujEHYDrXC&c)W#9qOa>zK8!te=t zt$Q3v8_jN@xo*m#cju^VD61|wy>8HP_B$lVnqJ!}3ow=9pOs{F%N^YTm6EK6l8hlR zcXV~5vy<%d&${S>S*M?SgnJmtuNpGy}snTCgWW zDD6ty{&O;n@5L2^F^2HWP&D!nIsyS`Og=ZE^Z^i}WO0O%W;6<#m>N0F}yMo;6 zsvs}+UKhjNfpA#~+jgWOdxKGoDur1Mg&9M57KXL7VHVqV&PuG8VUsKvR|T+Z<-&>J z^gJ@Yf|MW;1v6;q)A5I*(L_f4Fo;5?fck@C7=Vc%q*+I7%xHE-qmhEJFPC~~Ftll7 zr=d8kUg)|I)kT}tQd`l*;9eid=P$3GK%%@n?n~pvyjScY^%`OkGBp9o5(e15 z*S7zhei&}m0|PJ*SY$#ynO@_0eB2}%Xw4x&*iMbPbFxS?QN}fOpSYbD?pJXwYm{;; zHA=6bt7Ummy#S`(gJG|F`dcf=CR}*#3iPTJW;JZ2h378ristK4k};HFHEfu@Y@1Vqos@ zbNfo>4atlTMbr)0U$jkUauM7WEtud2iDZMDJ50AP4LTYl;(pZ|iz{~Gz``w*C8r9* z8uz-q?)PC>0mdi~su#f2dob)(-yMopmST(n$tHOAz_=7SfxRl zXJ{5n!?Pvr*H**s*T(K>hrMI9w{^U-1ZHu|1>2cNK)RI#1^su)^oa1I$qF6u9%TAP zoI&P5bv*aew#!Bll|ySiU+nWjrh5>j^G#@Saz8`3HA&!(U zWz&o80+_{<44eQMPP`C0wf?mL%tpLENEybke}V!mMrDl6j&g2(ZWu1A^obSr^Mee` zv_Z~{u?;ZxD+4TlSoF!Jok)%G)2-bE#@r{9DW&n$AOc_)!@fbcO z@*V8&EF|}YqN2($AMYiPzHDh(Xfqi@GC#s_Dak^$dSeW6$ekTs$R_#wU|g1A20L*k z2K(aSSQduir-b1V{IG-Z8(~a|s z7i6Pr`zx1i!%zzF>jLsMZpU>V>G${d#uQ@=7s+Luv%jy~k+dKR?TF%&S+tF;Fq<&L z(HUVDhFuujNT1PG@&#jA#1FT(Go_2sO+EaIP&iGd!d%3;L6FmwlUTw5SQ)O)2@9EC z9$4z7|AITEkb+=5PlB0ogu#I*VKDR}3_O7DLzmYD-D8(h?3T4Jpu(_CtQ>Bw(W9@1 zjmIlf=MSe|i%$Il_P51`VU-PYsdJXS$Z1tPG2BMqbYLhG>ZdGMvfO(fBu=Xj#FkgTJ!8kN&%HfKg z)*O9Lg@l9p-cod>#s(PMi&d#tZZTXiuy`sz6;^mH0J9OVkC5%#@5=WN^uM6QID)+@<29u@6)PhT1N!-?0TvKyz;-niE~)LXx+%nvtU2O~%^cDdzJ zl6^cTrpHNToQ-5**oE;chZdy_6NeLf7smg01>k{*0+38dTpUUvept#A>=iku^7}9> z{c#Mc#32j7^bV5{(;&e(UdIWSGOPd_f6E2Y8d{)!#%9$%pkDQ58LsG5Uk|G`ldoVa z#`3qicq+#1s8WneNmhp}47)IP1sHaWp$wN|Y&++(*y4Bv!!_ZS=&C`j$J;l z>y2@FhI#zN8}8DXD8Vo=tHF>E5j~_?Cb6kxnR~sg|^hFfUfH;@xvyDA#LLH)zZH}f(wS}YtUN` zs-ZM`;aav{|LTO{OfO=NYFBT9yMi;lLIx1Ra3TNTj3k8N0>CF3t_*OYJ$|-6-^u{< zZnXgO1gkeHukTX*D+c1~)$?)9c^DD*}imq+g^ippx zx>zl{$ok4KpGY`iF!qH_=UsBpOd@t}p$T|zh++INPMGJ6H2citV(4{^gJq;jcOY0$ zkzsqsV!QVI2@i7`!>7_KD|j*ERsTi-HjjAoxGtQ^u#033r8K%w!*2G<$Re|=gW-T9 z#aN8eAXywT46AIIOL-P_mF+WZ3|=<@aPGFs17Cz&MsdruO$>YZD-0I_2IFIfUGCQfupA>VhHZMWPX+Z&Gx@r< zUjblw%f=YnZUd@MRzrO<25wmy2II0M+tGzktqi+JR)$L*vJLa8^s<7kFAPg|0)Po8 zxQh-LGkU>}C=_4}4~EZr`=BUbr-tYYmV6pxUzK5On_*%w!!V^W3JjkGU=#11q0jeJ zfLWnh#%NHyQF(ozQyFFj8)KVcY^7HX8)I{g3q`~gODUlRCG<+DObNZTUkaW%5DfT( zHpwnOEHEpFE~HOoSpSfb&&n_u6G*@?XmKkN#*!I^o%=i(fUW6EWf|^GjFH6Pwtg;g zcPZ2T7aK4)o8peaO!1}_o}>#frkzD@!l)xxt5*JluRc!HvYtP^C72$NlQs48;*FJI zG1MVzoUD{qHiTiBVyOU&A2!zl?nvXzN26JUD?X-IFs_ne1sH~7i9x18F{@n~k8-{o z|L`;PT(A%AU25-Yv5&8eKQM;9*nVC0Wdn&ymC=+PLLcw9Vqb}C-`cy~1+#!{BhAb{ zVHk`>3Ug^(AutmyE5>$gY**U034?t-I-yd!!zgjT5XF~)E}~*wF?;xXFl=sgOdtWh zCbTA^j^+ZPRF^L*48JLQX}(qR-PC~Q@xI=A{nqGbF=RFpfF6= z36U^PxU)NA;_Y&S&GcNhuUVx#&E+CkwB1PIpm?=qJnFp|^J3PBq+Wo!$c8aOuq^D1Hl8sFiE_!40{0#$z>UK?dQ@1 zQCj1DO#gc_T;VLUcSY%rqQ>66HpAF9z+$VnDHu*ZSxGKs7?>4249O}hqKdIyW7`r% z!>~lcx+y*#fQgD>iBVoMte5gE49m0d=$Jm1b2n`0WvUT5I>HhGn8cbF!=z&I#L}br!n_t| zQ3Ufn`E&d^43km=;0g?Tx#GWehF=SKuW=)Z%VI1JS&_pK4wYdHH?Gb! zC|9LK)MsZHl6&LX!UGYU0mi2=Y(0;_JPjm0NQ=pw4o(ySrFyd1!LW;77IlZHVW0To z5Y#`o4Ue{)R~x5#KkVh7|1$MnZ91=dNlKKK?%i1I&a>-nS1h)DT;yO0!!C?*%NkT* z*d&XsOk!xdtgK-(Y;Q-=a`|BbV_J6fci@L5xGiP)#1lwKqZI|iB$;u-riI9WB5wca zFl^I{T^V3|7m2OA(cZVV?Zv8B{eM@6y?$>gy{FdLyI1$W8m?oc47)JapyKQ>+hD7$ z4BG&k^Po}z1v^dQ0s!#@CZCYl?0if>Y8fJFbog%!7#}>1z67r-JpwM z2qY4aT(K~WHPGC{bdJLP` zQu~L-Fu_<=s`i}nIyXJ*UzK4XFWuYragn2@HLioG2Ny#RJqDwRkdk~F%!PhHVORmK z;D-U&L;}GWI~In;37?T+#z6Atj1y*DC0|v-75mGJZT~c}UB6xTi5R*YJ^hBqI4-Ya zS}ilxu3r_vtX%E(y?&Qx{r6z_RE%8*%XKJOv=4UyfFi~&l5MIj+l=`XKWqbBfnkYe z!PxY7IDH%dY#4StaAiMCj?M`rLdUJQF4JC8ouYMH5a z{l6B5%LW)yY42+L5UA}sO!lIEG{v?tHnzp^Suie*A^@0R+jfs|t0IbUIPAj^_gjWx zs4hN=ix^na5ioBL?2%JOqWV(zTlzEYogiZ=?NMi5(L!l`wLG6?{c4%4c71O5QI*c} zoxj&QRr>7{$F4Yzh)UN{R+6b#8^cENm2HAm6&w-+2#rvbNDs*~!Way!;+7N=31h%8 zi8yk?FfV^w2qBy^_Vt;0%bZ<+ISD2wlE3~DC3*%Q-rNH#&oeExeXVtl_wsOG%ID8Hk|=DGfMw50JA1NbhaPXSi;|D#-xc8cDY}B3^2Cs zc*XYGX|8(R$#2XkKR)fG@3s4vUo*5Wul~k_REB8DpbUiyGC14nF9ED*@+Yc+lIOHE0c0u?(7Zsi#i17nt z*xW_RVOaW|De1z{u@i(7njFR(OE63z0mF7st?{rhET@Tma$&p9uj8||I3CzD`EzoB zglF5tBd1jD`d)p_-hSBj$*0?1Z8xv_YQKNg>wC26y!xiAW%&3&pB%C5;z4O~)$5|| zdtJ8V$Jhc>FwCrEe-xH9DS@F3)2uUH%)uCe1f{*5KPSUps8@aLJedEV#;_NY)z*8l zTDe{k#ZZi^H6$beNMV@K?54vmF^Gg@35Fq=N6wip=3orru770s)jYG8zxAqrUFW9P zcB*C7YyHZsR(|(;k_?JO1;Q}tHJMcujSnEfSQw`CM>3!*0ArjuS?o!I#U8p7EBqKs z6o(mmvFcUt#olYH{|m(uE~;&e%i1oSbWt3*cvLz#3U~bLiE!T@W!Mb$ac<`0?@LP* zLAwvh2g#;*v~GYwl@7`3pY>A;>sVu)_}k;3@MAn&aU|PoW7Q*e@``)C>Z|p`Uh7N! zF$NVgassN0DCJ5F170Wr#zYi^6WoQBdjN_bb}@_xCZbS=b>nOSj1^$BSiDWBewJV_ zUTr3`6oU38!If^W(Oi5uS#$-Xs_c!?*GK3d{3zz5Jd>y;m&Z)yDLy_u6l7 zy58$Jo?7o>!|q40yBO?xY^spEASp8oJhKkV!Q&;9vBWmrM2V8AfwMkA(-M3d22ijvkD6ZBx1OPex` zE0$pr#1fzj&n${c8I~-ElI-%vE{r(`y-4=l=l@Opu;)1#E#LQDZ7kurKYw@(yP(za zW3GA@VHjv*(YOE{i>JYuaKbdrLb&CO%&?26^U-7$(gaQ}Rgpv{9PdZi)We|=Yxmrp zo#fZWu*)qUFTSQ@Th(d za15u1Lw2w5*UT_y$LnI%wHtppi(U-7;8DPAiim!raRYE7o=hdv$y64MBY4+nitGf_ zjZJ#3$S^;doe8}lEuL9O7FP_Ae1ts;$o@pvm$5N6c9qYgcMW4Zb@6pE;I*AM=Y(a; zUY}cS{SOCP*EcE4u+5CH1YKgtTS5^G8wZ>)PB@+FPxWV#>HcVuuX!$F}WtY}>VqPF*CFQuT86DT+$9F_bq+OHz{9DHZ!i zCGYBDsbT-QZnj$E)F1eRT0u#`D4^?oPZh94aUnR!(KJ10%V?QAz~HHp2oiH)*l&JK^%lwrAEaZ}Wz&Si0(U zQCDyox`NBl4?3fv0E?mAx)v2A$`N5&wfN`*J%TaThcn08DGK23O9-A7Sn4ugT znINc8h6_=Ib9-bnMcR=~vdy!Nv3`I3MHsR->>AtlWYyytxcU)iG}tppNybom)vz&E z-fRffwn5d(%7$(b13yz1)C!gMzOrqvpKq^o7Tb$euX?X-+TX_xHA~SIuPfYQV~CBf z?(K_7ECItqxY(hQk>OD^I6Q(kCi>-&IYC7XhLiny-0#@r?8Nju7z@KxvKl!$al+iz zn@550)DMwOvMa#Q7{mS{*!J&ry`_t0R7N?G4=k@@-?wg|vLOtYl3ePXU(F9!0N6z@ z09Rm`-CkCef8E*NwU5P{u=yr7x_YG+Vzm@vDZ6^Ofjm!KIyQviWIUcpCi2~iGjgUQf+dKXsi)VWb(tf-^rPUso6zHhGA-yVbhf3DR{mhkJ;tf&?1{; zc(&cL9arcNIpgjv3ow=C0cJ3sbKjw}ml}-OFx#G4y|EYyURgLx{jgnQ+qxZbzXEUt zjLQOS{E5do>$L~G*7vHfmS?Z+==V9MR{~Dw_S%ZBLfgq*f_)(&Szs216R}t}l_VG* z9Uh(>AD^C_oSK|QBcqc<#V~9RQ(u^z+wkbvi-a8MOqT3iZ#cr^ z_IN-fPZopWwyuB(l5L+X468%dZ?3;Z4E@QjdR_Enm4_*mRrL%9gHcr|6chFK##McN z302hTucynN9?w#7rBlhfy67_4f{4-EDl?kJLmZb<;c#?EeNRIVgv)qc3@ZR)NVI86 ze_u~eK|Wuvs;ev5-5pY~P9P8o_r-+apAFU=Fs@WOg1+}`iKiCi1uf5 zV-u4zbMp&J%S$V(7$aljM9$Q^81Co<<70-)Vr<98`a|p;E<4SxvF+*@F7~|W2URdM z5@Y8m!@*F*Fx+cGFO}^il|2PGLDx}HOzTofC5zBoTE-oQDFHay~c3LD5cjAH~ZGCSuBgEybE1jd=m^Sz!L5X!%D9hot=RK#y$fxPg!y? zJUKctJ2^2oGqW&fUei-Ex%@B}N3KmAKJ3}KrNyPS<&}+<)y?^Z6(AoP9w%&Olm$nb z$1`$P5y)8?uMQL-z{ zWk{a19_-^`*)Hk5nla@5$pP!Bmr`R&9_ktlbD6YCe@`eB>}7ZLr;@|@oG`pNJF~JdzqYhEH#vn{rq_f0gU=y6 zhFj=eUE5k)-v;K1$=Ond0azJ!VJsw<#rXIfJPEUlZC$L4uF@;#hzXwpy&VBlx+D+c zk=TD^6CVy$svgx`;jI)@j2Q_J%*yc~bUc(d;Jx3dsekgCW_adVC8W&|#Qsd=afM z?43Y2o`6!s=o6GbDXBEQp+zarr3{;_L?8K0BNJiZ{T+rW!$m*L0Rq~>mvpWd!9XZj zeEEYsW5_&a2QF;YnLr#ZJ1-+=Fy|b&cn+KQkLt&V_g!tk4sqy8xX#n0_S;QgF%}nPrIj);f zIyyFm6W-e1-`+Vu*upR|voK5`!D#}(t!-URtwzml-KZ4iGSNjbpRBnHrMj#kpq9lI zXw}tY6i%6*V8=dqxbBo*fdi{VTnF3Khoxl|Gjrc!7q zokk-kMUAY(%1HjOKOR%1V^NffMv}N+J}AtCQo@O7FP{j{u|B$2jl#zN7Q}ZmzPBh2 zYban2uInX)NNMj?`LUG8B>T^9B8Wc1wREjvt2M#hJ;q#ksB3rQMCy_2s4I#f9O4AfpDGbAg_LUJk03Y$%-ZR-kRoWRvNDRj$f zw04=Z#wCfbq@~c^yi$rysnd^(X& zr-u5I!~OlknH1${CN)}8f-!3Xc`g;tC%`zGi!&lHf^D|r*qJC8_oc((WQ6{H(Fum5 ze3@W@;a^7NlQ>GJvNO~3d%K6XZr;6p>)wr{+nXCZbF+)1BNO@DP&}3jGR_A= zT02{s+Z&tORKhc0i_EFyoKtdX&~zit`Bc>c~V6=9T0 zA}hiwq%N9?8V}veCYNJ}A;F zN`yo4zMv@98;FL2kx-B?W)$Eo3p$S{4D|YYkWI3{+#@faU)-IR=5pgmJ$WI5auOZV zzSCR~eLXbm?DU#;G24~4?ZvPHtPIO>upjW5iV{ z9gmIVb2H;(t8>%aD~tOZtA{(AyBq79t1F{JBcwDl{dtHz*uQb-_Wiqe9zgQ;*53Tw zQYpjDO>Iq$tqqQZWE*3?j|*eIEto08V%Q{?wa-Ye>iG2U`K*j)E)Ko65;w@HiAW!or zh`$|9$E6%ffpK&o0mk8642*j-MTS%15IVtdkVJNYVKBBCE@EuFv53QMUd|rc z#n2Wac{VH6X2y^dRJ?77(u=`pWP8!JPi0t~Fvl8($u}s&0x%9xd~ahzlfl?|wKg}q z7#_}LmEnWUwHrH|dz%|uYpWB(qcEJ!3@k3J+`Mt;-ra{_jIp!5zr3_IHcIj>PmD&I z4nJ(1a6=0W*EcrRH8hH_8=9IMn_Ey*OKWp$8{#^ETH8BBEghXA8@9Ht?)GkX0owdoQ7rb*Oz1F)$Ut{jsK+Pj^LIyrJ&xb=Cwc>^NU%TF zi|~^G3~~m)Ol%^Tm>NjU4E4_rXXZw-^TQ{!IGhzxKRuXcO*ENLBK{DKXX9g;*ho4u zoC*&m`_N#bcOV|hL<0`Sp-d#y9}c2qIFRI2>J7w0ei2{Kkj%Lj;I0Zh9H{Wk^(SDM zaK8w%iIHgOIpK$C5;|^IF+Of2;^Q5R=^(JX+TqhRx>XisLXABjR_g7WkPwY%Xl;@n zGSIPy);IkKemSf*!+2nE!eHFc(9qb}*xU$G4V1WI8hFHiTpwvc3}rLZW1}mxQ~2S- zt@T@b+rseV$Qa#8%JBVrkMP6F@c7tNS%w?x3jl*L3@gSkToz*>DvPlItmtA0`evKrvQ&#V9h|>F??c`sfGp0Yh(37Ys*3ei&AOvxzXmRRXZkJ2{Ym#;L(1 zWKItxr}L&<9L+C|<(5bD%O}gZq0H<^KeW#brwz}}Ur|ExST;J^A06or8<^7tjPtP| z80U>cE?}JQ3xcr#9OL{7_C);#U||@H4ap@^hB4q)Fosy7Xu3%RU0RAFT8*Hqy^}IB zq%c~K-rLi3l4NrO2bupaeI>=Xy1=mdVL7tq(rLBhpx1;DO)W6Y3xI8gIa0Bc4DYNi z9c^#G@Zsj>&idNa=y)og9LNl=F0S3ZdGGQ4ClBvF!r0$Fpk{J(D&Id4WtgHb!i?eyF*-rHb5H4vZ3#>TUe z@l13q6CO$R4JUht;>IBl#zMfH!!1Yr*>Eu37f6PBP$Fm)5BT_=d|MO__$)bKYwKa3EmfXQz`-M_rf>Y*MMFcbnW{95EC`Mj}Nbsc1BfoLN+r?y+p&F+lF#K#dsO z)d3$ap)xS59~Op*Bw-i^~ z^xo>y&Fzib`#VQlTZF{ZV-uM~YA83nzPxe&_JgMnpMmkcTlWuk4%e2}ZHBwseZnvp zL$57J7K{rqc@bvCOr4~{EQSkdeOI~lgw|;S==suOz1myhyC9RYDGH1W4C92mJ78D< z28me6m+12oLf{4oP@#7y9XSSgC^bEpfMHOC%+<;K`t;z&%#dnpddMX(UYQzLp3E;z z7?>g1z&vU&W;W@JPezPrD3W7~ui zvtyIlWO`&^bYo=`5B$mFPr>-Xorj0JM^HUAM(boS#t?Bvb+-Fj8{3-dno(VCy-K_> zUqb}OBDp#UW)dW8oLq{u*66QO{^ge*<66wU$o8cq{#Ox1nI^51C^0R}mR2&4T)OCA z>=8fQ)!EzK(bv-v^LNDq-3VWY)62$!xIto6;#C81COVmm<2iA>b3@7b;l$EddUZ0p zJv+ENKfJ#Gqj^eIwN;q>4MCG&zb7&Bk>7-OA)Ssb-n zXy!PVR5`NHVjLimaD9D4T^(g}eO*&sEhXuLuC`Vf=6Cf+B4jd^;afYK_YQV%?d~3I zZ_SNQ5lgJWB3+j!vTPd@`=U_RQraVo>LHFZL=Vk{2Xd?klu#Z2O44V7I;>mr7% zX%nj(aT$8DV6-$fsRU+|!ft97l3`ddwiyolJB4AWNcH;rBmP`G#08zE7Lh8AF94p( zCrsop3VVh?Xaq}PcyD0@K{7fl5pQkJ4{tdzE6M!1jWHyH@np7dygxLViB9xK3K&}s z*#s34f2J>hAQ?$?foCqk*f31oh)j&@&}(|JWjuz1uFy;9m` zIz52;`v+5*!DMbUeg?&|BL(#jal12a6@}~Oo+NtL7p9^xqRb2y4Ti-POI|{*vt=0u zV*nP0TN@i-xTmut76_0?SBCf3mWAQldwYjF+w&9C`E+J%Xnbd57Z3d6lg~eW@*J3N z?BB#QPmj-(^~2Ds0%M6QBsSIvSxJU5!Otes%gwq#WzlBUWsB#hqzx;ALmo{njU*R`6Z3jTG$#_q1J~Eqphibv48xsmO+8(0v}emQd}n|EXm@8} za%P}EJ3c%C!_OW;@Jn2A1%?}In@CA0z+wo-&}+jifC+U^g*T(VyyfZVfJ3F{PKMcA@OJg^d#|76rt5d3bt5YIsZmmwBn=9i- zOU6s@&zpFIEo@KcH*x0U{VRkeqbV?6bTFRH#inx6>Hg?M#zYjO$zFqT+(Z;e8hVCg zr>!T=JxG?^1?dZ;-d-d6#~qoDa%awo18|(d8)p25LoXv_2D16Vtl@TWU_`{I#espb z{LuK|;P}AsM1FK8TTcDMQ>p^wgHsp+b|OD!ymw|eMjpVqKM4+5Fcw#Ax;%VAgRwKD z2XAa#*{KY7w3ae_dw1*p;ojYYgB!bhi&L{OJTx%2wXyf~@$=6=`|A0ppFeu|^yu)` z#`^Z;#037jHP#t`o9ero8@gK>k*~EW*xnNAXzlH6 z>+Nif``Z)2_Ee~=Kir+|>lugzXjP5(_i;g=$wue$@rA+U(r_A|xjkjj-Jcygm>)V? z9J#qXc6)W=?)ub&jcN3Fd+yQJEPA*(^LXP}kG7^CZnDngy|wYXs}r}EM{X>Q^5^?= zgJ^dqzcrQJ9M7yl@^EsQNP8%bPoB@kW^&=F{xIJ}#A$^Flc9k`kWeQZH$gl3WKKHa zS@Ov=MWvgsI3&Z2{A9#YKl9YNpGZ1A$SCk^W+4h@bD4vh^B zO$?4q4v$R_jZF`a&JK;v4o}WGS{R;O7_^idU&xNlt1_c=nbCR5)X;Qta4Mdkh!2bl z$tIjm<-*AvCez@f1Axv0`VwFmr&NrGYwKX^`Zc_<9MkrehCo+) zq=#!Ijg*~8VSzJr z-md0&pe-5dNcS0ra}mSvXexvcoX$jWiA#gYmEknra%(ELH#2xRKXPMX_~zos?d7q1 zYm@iary%yp<}CVTXF>FAd;Zhy`A@dy(6g=Sr#sV6wx=F%PCZ`doiczrazHj)Bk7)A>N(YajMgcg}zz6=^pg%Av*92h5p2IF|ZBrY7` zqDcmlOUcB-NJbgqatUy`qlmew2=j0<8PFXW$d3*Vj6p4vCPzj_N5&B2VVIHzy`vMe zqmy%EQ}bh!Or=~Ln-MLK%`A^t8k|}d4NNW#OfKgqmU52z$L7+bv&rFUqoGMi#vw-? zhYZOQA=A(!Q$d#p7@Hw0o!ul@=?S9&4#QkbInWJtCm80ScW~@z)Ai6OActcZ-kO_p zF+4vxmrG{z+2Qro?I({uefi?+&z`@0^7s?Fo3}Q1rzU3y@@7BFdshefg-Lt2TabGHU?F19O$%n8<8T8h{Vx zhL08?aO}>?C{7jEijRG=Gy803_LJSY&kh#R=S6+CH~)Nh?o-~~ok0fUtx3W7?yA`W zCjzH~xZ-VG@kGC1yfR|EF>wVLN%BhKo$%!fER5H+Oa%yg3npwb0 zQ?sknb87`HZcLuk_`)U{o8Leqb4J6n>!P8VwSnp7{M1r*Vj(kb+;Vz&h5&<5Ih7xC zo-aU}uHcYK8k>Pe^n-Vi`t3BiQ(Q5ZX@_ABbR90S=!Xr%EzK|-_0y_7X834r?e@;j z{euJi@Zt8(?D$MN&IvoXwz4G*fBxdjXHTEg<4kum1A&N_m>Tw`8MXnIo*Hq#TFRBB zP}W~>s=wY`XY1Gxmt|O-a9>wj*w>0oAko_?081cYoNzuy6tOsz!UGeyD!_yR5O@M$ zSlwShFAkSJKU)6s#>!VWS1Df}F1?^0w)f^f-JknpZx)A)H-5B%_nu%2oC~*zkZp{| zGaF<5oHdH^+(49u9^o;8G zX0kIL2FE+a= z?xE?GT{O9DG_kZZzPOFX7Pbu1b8CY$E5MA4HX+C843V>G8xmcZw%!1@?~{A0nrVIX z#`ye1#U?>PNPLoE!U-HQ$66VV1%lZyT|%VU$F}F^VffDOE)3s2I6T!!JMo>eEkNFmPgj?`Upzk<*uZwb47ti9;()8g8%A54-3s&2^J((R_uEz0NJtbhk~B^jU}gtRqJWG6PMAg< zF|dgumPT)_j6`N2FS7aa1Y2`$7MgR$+6 zwZsTZn{cvjSXma%sO|0yVFYk^nZV%6I4i#a}Pb}h)vm>*R48~+F zNLi41<95N!K_-FC08w?taOJpR)4Ne$Yr+W_24GrW_+dI#VYoj+mr!5 zMs6&h86U__3=cUPF^<>qx-*m0vr}dk@FK$y7Zz5QmR6QmS63K!yRo*hxw^5lwz<2$ zwZFc7u(@+nw7z?DegC%6-knuTEBkj=_U@wP-8)M=x97L-%x&GC-ModS*KbU&?nCmJ z#n1MA8xAcXsYdQszW`k zb^f;cP-{24esq2h~#FU^6_H%PmYy zY%eatFufbf@Yuj;B*Y}~)WY1#!~0M1!(V;*Eg>=KHBu9tutfgZOpg015E2uFlO+S= zH_C8reWBa2Duw~LGQ;YG2_*XaI+bAwByfFnJ>Y@uD1tPaNkQz)OZi4lt$pP< zUg-Vp{cY9n@9+HK!R|jl-23N8yWiYd{rWaR@(SJ7)ho= zVq-FUh)V+u&kUxJVhqWkt3yC%M+WA{hGxfx=f+3orzRJsrxvDXmS%Ch^UI5itK2JO zX=P(=4SKgXH@CO9cX#%7_Yat=!Qo7zSWr*u)Z{UZ#!P4AZ+I z4DYOO4ChB+m{?+Tc=Ex$Cttq&mUtN9hiTSv$szdXZkhOD=Ci=Cd{!Nu%%p^CYOXsk zjI#M*8Eh=$jmtV=8Fftl7|9CakW2Ftq=k<&!zH=3wubBNjWtL-u&=q^*HVjmI~tKV z;b@OZN2EiY;)L_D9wK3!Fe4V|^QF6iC}LxR)?ALf0l8eR_&8xQz)yFb=G)QY7q?cv zzPtYGyBoi`w~55~?!opS9`3*`NsR# z`QZ7@N1xv)>gd7CgNH>u_+szD7rXag?%ex)>&|DJx1Vp^`fTm? zrzlsM?8FVgI`KlGDDc~!*p}pyYmQ! zi6syzVw!bK^`HqrK3q~0L@&~;tH7|6d@~&!PVa^pFmL94IFy!_UJOfW0+KZ^Aq;!9 z=@ejPm?#1Xz_jK}AmKOZh{_CaPSTpo)1BeuB522vMw@>|41Boo`HdwQ{_4(}G7QGQ zgWE^D|MFxX3C5J@cMmpU_%{y5_~b8d7QAtxmA7LYG7OV3zOgU}#)q>*E{xa5va4g+ zmC+1+g^ME@#28MrFq$pceX@Mx zDJ0{T7xwNGErap&%As+{wDqP}2gjGP!*j{}1Vb!Hwe`hQ{=TTWF-UiS*<`q4149Ex z*fi@n?l@r>W~3Gj$9tKKkeV7ATAZBRB$jX(zH@YV`|yY$pW(q~94Y=iGj#jreHi}w zt6zWf^>3a&`IPbS%t%^VTqPOKvph&m5QLM^!xh6YFFT^(qov0ghHZeEyJV&>73Yx3 zOj0fDo7zNmjjgD*p#_=qvC2LU818DUMa00kU+4|A)&<+@@xaCjcQwU)EeU^HDrh2M z(!v8#-%#8?nhG%9hGZ=1ETT}8Qk%-s0YTCLC(IR}rko^!0r=(3WnzPGZX1Swdw&b} z3&5cJr>6)1`s@(>36dZ0Aq*J)-GlW4$#>VjbzJewqXmKryfJ~X$jrr+~#ktL; z`K{Fz#)Q+%+27jU+u7OQ-96erym@%z7U15#d;i{phYudzfAHkN!>11(fBJ|)1<$@f zPe1wk$@6cXe)jFN7r%b;*>4`b_|3!5zPtaz=-y|)z4!dPJ4N08^mpjSC*K`C`|ZJ# zU++KucJJZ0yAQwKe(=@iy)QQIe17bccORG_dE+MOi;2a((Yb9f&W$gohGq=LxZ*^H zQS@EG2sZ}76*EE>NQB{rS~JB04!|0Q`+EG`-UK@#KYfy^IHVNq$Zdpy1KH#eKPyg8A(mhtRo~Q1p>noPMAP~e26ph zhiidpkva2~aKF&Y^d*^ar`(n`Y?5);{1%el8c|>nEgh>QmJoUkz|Hm2jsswta(G~q zQtNJx_p~Mh#tEB#jY#)ktYnjYVWh~;+?%vJ)gByp3w{G0P?cOWW`{eP{XHP$Q^7Q%BXP-U&^yRbXUwrb}H=n-v z_S2WYeg4IFpMCke7hnDU`ImqAy`HXSW8YR_L3iV;Wb? zfC`>C%wy?r#ckbw=E5^tRw7jxW@-=@@Ajq^h8l+bfn=B|jb`5+^0F`t#xP9N zl>vBWFh94wOy&;uZjv7c;9r0HoiNNS(e<@0`gBN5FomCxSQy4nD#iw2@&?YF4%kCN zuK?UyoboKQ_+6#kp+YK!ZD2M-Db2qVV|!@09;>OYwaIiStAt+hz(Owo6G%WWDmdX# zyENr;juRe9`X?PHOosvuy0x(sfdmW_NN|bgLJwnP!z34h2L?hSTjEtKiV`s(f0|A z9fonm!Z6-=XL<<9(E9bMp^fQbv^g`fF*~|BH?}!X^L%P=Wp;mcZf|vQe{IRk^W9o! z5ZA4PeXg)~iFa?`zIW%&!+Q@NKX~-`(UYf7o;~~I#V4PB{^|3V&p-R(`R8AM_VSw- zU;Os-FTVrbm*4#J=imGbdim|2Ui|t`&wumppZxkiM9;qccl6}j|3r_z{&)27%YVQB z<-gs1`KLRd|I6(cf4ueCKi~NDcZbh@t0WU$NN54ZbKCc3)^CwU9$(lUn%>BcE%%Si zF{UEIJy+vA6Fknnp1AF#Fbp$X!~vKF5*&0iw{mw9?sdph6^FBCQuFfMEY})-CIAb= zB)u5|%?ML+Yc%V2whmrA{}O-^U3HS0*xcALcNfg&CA~(o&VwmLZaC3HAi=N%oG^g|4Z8Jl(!yC~m_Xu~;iE;eWDrPX3&7t! z-1`0F9RXNM04`;?=!!RR#mcaxDTs>26>Cp4ebDNP>02?e@ysyVnH@2j8Qq#4-JToU znIGR?nAlmI++Ci5-oy2U8=Ff%E&d9^Ah3=4rY=DV-H{pYWL{l~9<^QUjV`?s&Z z`w#TZ@BZ_v-~Z_&3=xk>Ku!<{A8ZtU$k0RR7_y@yv@*ShZgAKi2I&Q9XQ zy<>Xsy;q6etAqqXLcLc62t-F9dPnqL+-=-@OX4&)(0%4wHrppT=id8`&*K>@vP44m z_Af8beA{H=#|_fp7)1fYIMYGNiRsm>S^z8&%hA0CjInD173atZRGfWrzY>ND(KP`} zj3UKhCO0RfN8p5EBoKsQB;bS* zgkyYQhA$!`@ioK$B@TaK7(rN4lA`$`lFUUyD&qyg?q!wl|igPkClwMv`SXolaDl2DIR#vlEHPu`mx0Y91$KwkG^^$s_ zR3MVqixncNN-R@L1)5f%z<=b!35%S&PbSGY* zr5_{{{p&xWBj0@1kN^4)6yu1#Fiaoi;Dl*_!LZwj?>tU_??pLboaX*phLKhK;)nn3 zC5RtJRxKw6aTvKW1Yx)c&`XPE7+!+56QGxl$zT|wj&(`2m!KKOKjbh+acC#NFzh!@ zk@>MfAUP){5M4%D(LvcU!8x%ZP*zMR1bVX*B61QVvy-9_egSYHBMI~tWu_NqXO!e- zmE`AC6c<&Nmaxk!*i}^=HX8uf)$o9CJshG?DwZguGL=lGkt(z@rB1FgDK%z=wn?dL zR_I!k`c{>}sxq`I4DC`whnSMk*iod3?n&w(IwE^Cpt7NDF!R5l5&|0#9;*CjI=aFS5&UCH5%8-U^E+-aTFAm z0$`|~C*;=%;HGjivr(PIvCh@q{p2~EB9H#_dvdJ9H^P4}ur6QDab*68*w}xfBK_?@ z5Jxe-iY+Ddvb7&i{)?=sKl2^AYT@i(o_PP;qsXzG#@Bp%F0`wso4-(i;=bmZHAQ2Ng!-(v3dAIG3?{)4u`h`?vQ`_HrA6B`V<;3#+W8`tCC zdY<^+`_vDrk%3=|(J)$z>{qOruihR4Ri;ZPw_TwEAYPzC~}eYK?7> z#?+~8=+cBW7#(itH$HR8_rzIu zEE~ihI=wlN{1B%Yh6lwMFOm}I>c`eEB-RolA{mKEXc$I`8K=2iW>!*sBGyU}fX`k+ z&KbR(xP2otr+|*bV7QLUuP80g&&fljBPb-)-P7~*h4bGZKlaTLVu|rz3ceT3Fm;am zH^5jW@p(-I7DQo5Aox6X_WR@Kpd%;F)7ug8;%m{L;>&1Z<0ZC)L1bkmR`MMA5ilP) zg1?Zxv}oG<@%wKm{qyMe|2%f&n-f$a1L2osA&&g>{13!JKmhpCv443S|IX{=5uejP z(hLV&I1YwG+)w;Z3?tu#a~6Ke|Ak@NOW;5U9WsnF9UXfCFfII6%VL0G3g9FF3_py& z7sA;P7$dL~OZ8Mb3lq%YQaiO>o80XgMv$?8FU|bp5_*!P$#0Kb$=AuOBek^DlfC5_mr+ zBEA5O?~Em!^u|k=hodKuIe}@%zvPjVEQ^y6t)=;#?Y`o-ZBA3^vU2#b%%$}e>2 zQDfcc(<41jN3nV7=#Thylw$gaZ;w$r{^NHie*Bj13Z~oA(A5LE9QzJJ1cuyCe(!nu z2Qch+_E^CA6JR*#(s7#MDBp8m$KlKfPgEShFfzBL$w6oUrsFUS0DY!|oq#2#8HO>2 zqc~)kHp8?ZrWwYuPEwQrfQgEe@i&q_irjc)oBzTvn&Kdo1tGK;5haB|`ALxl$x#KV zv4v@b-eS)5jmbdKYcjT)8`{iG9pgx4ns1_AW`#>q;WvlXcsi})fszh3_WaJPo<`-T-jbKx0Xnn3WW{%b-J7yHS!g} zIJKDMjT3Sz5Q>p8CZRYy5zX^1K4E9v0#2Rx#Gg1A{sz|yP#HEbjD}1sRlvG-GSPei z-A$-V1{^Y6kd>X6nVp%z#Jnex61ax~45P6Vq+vM*`bg1uN$iABCP40m%_%D`MTH#~ z&7cwW{3ST>li&V`q5tnNNJ95c99oF~goVI&hMR?dIC=uPYb>@U3&wF-`5Ct#&bS>r z>wfIK=ZW*4$1ixDyx>K@rk_X8c^p6I@gu%~5<2wI_78hQPsPIUkd+BoW=<`7!~ziP zWx@)h6Gy*?P98ggLHn~uF*!(j(jb=;-(NaT1RD&1Jx(3*Izs@4kqEqSGVtPwVAm6& z9w#Hb&w$}LzYB+6f@U~B#us*?I57ZrqB)$Ft-L*j5vIFxFdm=I?y4pMl<}C zksxuHgkq{}hY|@eMyi?E2}abRm!M~t(3^qEU{P{daY}emN(2Oei&A5X(&I}QiKUF> zGGX8@~$t5zCT&YrOHEO+9XVM$Y z4aR1Z$pU&Cn>(9Zx-Hh;7HeN~Tc4$4u(@lfxpSnsYt+&`-rO?*HT6!Kx+jhQ)|9Sm zQrkJ9=@?hFjS^YMWUV98mSJ)8AV}t$`)f@7)dm|&+l_z>Ujd9^j|s+H1#)f~WpzkX zB;{2h6r&!|M8zG9$4;O54p$>#H6Jz52aHjUARd^CzzD)Pox$6{-@>T>fa@U9-GTef&wC!b z;CEbRA|&HomOMe>r4hi6XLL+wphAbti9H@{Zl zLeerOwv39JN9q~}YZ~k{##O2|g0ZNfP+-XCsdKC4%nB6pYSCPQ!yW7dDtBn2fSo|1 z_?$-&&S5y#;gm$M`R+%6gdmLLJc2OXBxbZRoD%Hq9UF=YT^zgw{4m-iau}H~!&oeU zqy)SK%`p5hnv*fpifUawU!s(%5Q=fE!>B&$>}WT|wO{VuKBvy((vXv61Lt?h6MRc* z+z_(4SUZfY!jYrjz(U~QhQ;`pIyrmsIJOwMcmdaw_^II@d>a4Go}p*GLe6@H9X|2S z8Bcr^f=}@^XWRqNyOU`w%oU!dRu&)`4w$K1O)ucy1+s66`i0HX_=Q#JWaHmSYIz7& zPEosYTu=Rg?IM`>^gMIS=iD)0Ow0k`3nu|Ef-uc64s_9e=l>puX)l2|Ofw8Sfif|D ztOJLi?L-Oc7oVdsV((#fgO0;=jRR*o2;myXI{b~qjeLp2q_sFR2BDZ1+KQmE^eCdV z=(3EM@{D+>G(Dl5kyMeLT9un#nag11XL5>ixFrQOp7v_P520M|#=Fr(3+MYR0w?oxAqwJWLw@pggChA*8 z`OU*L#%x^|!B~o9MFTPwxiv~U6sHw(k!M3k5Lz@b{ejL*kHF{)ULmJle6Zo_hhyiE zC8ilh5XNRa1YxW#f*HnS3U#210KgeZ$vGK}g6te-Is-kWSo1>mou6^Rh9X2fTrUe3 z>gwT}mcm4}P9agrL<(V@2pcDmVMDtq?1Z;}z`09UsC5=e101sG&QDTGM$!w095;jD zask{@gv)WTLGGN}@r$0P&}--Jf7&bTjCc51@5u9hQ5XDTF8D`Z^pCw55Q8UP;~l(z z-Z%Q3Z{#_jC_FFvgkAIw!MXJu+ML`205i3MgG?9V(o$S$ip}*{xkO*Cait=ho3hK&>`IV(Os0cVLgkOn(FB8@)r4o%?p;xK( z8l6#RFc}*g&6dVSE1|cwtF5i4z0=;_IS6`tY-6_m$zJ;xfT1M9(%kX;R(3;7<3>o{Ebp4B3+oHN>UfJbPbk0iJ zrs}N|z_`{tz%}-O`LPX z=6M1S)i?o$G4+gn{n%9tGmMq3VSau|QBe%^fuyA7GMK1B!bqUKAJq*o3^RcE`}p*HK*EKV^>4(}xVh4F82;I=4pWC2*z#!&RxFz?j2~ z_&dXJxxg6F81&LYG={GL!zTL6YJgM z8{LzeofBK_lSEeP**dY=GPY$I-2}!B!)vCYRpa1_!M>vHThjC{sCwq5U9;kjX<_Ra zFy@&DI0hRV$qGelnWPcr50vn-S?H-C#XHyugkl`)U?(sZ4TjIU`XStbVUoY17>1Dm z!!Qz9w}qP^$m(o=f3&LsU`)>;EewXyP>Osn%rFvbILCou?4?I2K6S2fY`3!x3pg=K0{HOJV75kr{3g4EHF8M^vU~Or~da7X9>yX1Yf*@u_Qg#-;Ey z*RW*Q(8NnYaV|m8muQ~9L}q#m$3-`9B3H5;47U$qg@P-l{w`i{b2$g$?f`6FCENcl zo`UEt4VXD1BO9({@*U+l7zr>O<4+EBRH4}w`QgL71afPL!#L9+2*XRzarp3L2O0q| zf-rmnbja}G3%byZ8i%wvksRn~GmOS~DlhSM943w;GX@M-G2>a82~ZW#%}QqHrg8E! z0C05yv!*DgwltrPz(RHfel$wzYAF98Qp==Tg%SXp^hUF>p{0?~+h*--YbW$}b@g}m z4%_<2di%x^d;5oGL2v)aLf`13eQd=(u{t!hH88bhpWf-4-szv&?VH{0pS@z6z0x&( zrGrx240&OlzT7&s+cLS+GO^n{zSB6mWggjV7~awkZs__~mAy;yo;hHQXe?|Q7a$rp z*g3i`mb$%M+JsPC#M2-YXH|;RitEs6jO+wvmtZH*RE*TbIXC|k7d${9xo-%yueNdsJx6U3ijLUBPyh94}%0Vx@ z1SA$nQLxL+E5fy3VUe+(et|F?uoDQybb%Ni_#e0n17_yhFesYTWq#xY_5A;j(2>%S7N?TLIM5sOvv+!%ftH~F*)uu*iq?j;VEum zNr2fcB*8T>*3}=yoe1pWK=U4kz9Cmnzf11^*bj!5BTD^REn5_FFQ9fV^8E~49qDm4EWhLKx4^b$x-{7($iSz={r8m+%GOks=+ z8)=4zz%ZScKza>vm=@wN0A^<;R%a)%bCTHEDb+ct)p_aM0tTlrv!*y30P`z~1XX1K zSi)sVd0e>w2ABY>Qz`&(gHGRQGB=x>Xn@;0dOEvo-QD)y-a!D|XP>kUOxuQL?W6Pd ziADSPvVCG@aB6*EdShs2XV9^0pS^6Ky8;c&Umcjc)<1Wx+i|^f?t0h!4LqR^$F=s^ ztJWF7e6?lrGB7reZ#RtY7>BoX1M8YE7|S|l#MVh+%P2YG>21~8&I*}@9Pa9Lc^n1W zHPP6HdIuVT{=zWUX3`AP(@9u8fjdPIgt4j!W*F^i=A%t3?|HQc4j8}A5b_3 zz=sSU#|Hg#o~O^c;YKG9S3gEtE}tt>O0-I;8W_VK7Z#S|vZSckMBkuL7Y}dP3EWDF z3NjH@gF|iN2yTiz<977C*9q6aQ=Xx)wQvQlp-HY0>7ds&HrFe@$SbMHH>uPor6eG= z!auz{Fs+h)`lXfO9lVcEeUpp*k_!D2^StA-y<(Z(F$}M$bdQKskFX@q&_s_Q49t@G zEC|Df?mnUJUO~9{#?#Z&!^6Yf!_5no8xO2maKQxxxI_R`lb8#JFe6M)-;<3x*yP}M z9stJ$k|2zZH3Z@GaQDMF42E&0gPnkvIP}ARkHat$uQztb!xF#BbVuvDw9@c)*G5l4J}O;tEIKQt*fiEm!`M3Z?w-oJ}@*jI6ONrGB-HB zJUqENJiR_Ly*VrVIc~Mi+^|etYn;4l9=~cDy{sSF)(&m}W0h?g(OA++Fcw%w5Q@3_ z?y4_#B9F=yrMb{LT$lw^TFjW-fqFvg#u)Qr4JE?g~^sP z{|hw03Bd$l((MyL^#7G%*a=8pobnfpX@>EnFeYC^=ZDch4~#Jk0*o=2N2@k3k&}}Q zdb#?{qHQvCiFYnZ0S5xzRjz zqjBOIFg6VDz*LZEY+I0ZJEZN?^_DTXVjS+O)$Nt?7TAdb9y!@D%7vKtK;8L}VYI|! zQ1mYhBM4*lH-a!076tkGU`Q|}J`QaXU>GhUH#-~SftW4APzDu*F92Yg;ZtYaPoHr= ze!>NJ0fh!dR}{0g3M1k$7)GkCqJoo~TZ}4RNMwwcf6yiBWQTbuR56eTCc;tftozZ6 zKF2Y;>K%SQAofy73Vg3me2#Zgfmd>=H$pD6Iw-p)B$pSK&yOgqk1P^?ExZ$6AizhV zdA#uan$Ya(;7nF9vm!XXEF`@oIJqz=DK{`KD=?M}1t2p+##=(;G2!A97=>+1J^_KK z!eEOSevv(5zMlSG?!mqup}uZpg3^Z!S7O96+TR6=54r>a;G|FjFy@aKk)F&bFXV?Y z9CVml`@hCvIyLbZhT$ma%zvzItbD z?e5sx{n7OY(BKC2$iDem{p*jRzO_d^s}DOD@3+t2wL11Jj@!+%w;HE!n8vRe#xCoJ zw=@Im>b@04&!W6@R@6E{?1ZVm2Cf+06k;=J2jVJGvrEk9VqS@67=L_+4CC&w!#E6v zvG*I>4zY0ys|GN;0frHW(c6z8oW*2f{s?o*xQpRyhEJSAPnz4Q({3lowLC7qUcq^p zMRJiE3`3%N8Jo=`c7mB38JFl69OmKek5GL4%z3f}4*j1e&VPUE($Nc^#0GnWob`)F z&H)EBulOAQTG)myu7)Brzp|=)$_l z{MyJoPGmMaf>{}nQ5Ke39EyhOcrq6d9G!tdt-$ak|FHO=u;{>$h``_w6k>vcf&v2r zgZ=%2{Jp~hAWz)?5=jrH1-M}kHk26R1_9uda11hgWkh%b;LK=mB-St)M2d9OnU2m& z{2#o;*KrsYg7(A6PS6a0d6EVpy2}C+OpvG~Ral%NEJ~$SU!1`!Naq!0@QbqqCE0Z) z*@Cj%`pQBPt5{rJF6CA#>bUB9o=#M6l!{GCS%XH|XwWw|m|7c~+AS>|R-E6udV6er zw*G$m@W9~c;K=02_{`YE{KVAa)a=UC-1>xL3*mQa>FU(V_34#cldHF;*Y~D3?@n#r zgC;iak8eE~-+VN&^>}RS@yPb$;jJfw+fRmep5i&U^=x4CY2U^Z+xp|4l}BAm584** zSr_iM&ffvajZ-%pCa)Psc7ZXxF&u@mdk%*?`eX+?flyrWB|AYg9FtX!<{xYd`kxqv zk-)ld7zwO83=Qz7%`nw+NwR7%66hHwX80`e5@f|O6^9XlPXc2~r;c5`bly8PflR_oi#LiCknEF+V0G2{{&%M6Q2506d=jfxG4h(uop7BPi|g++t} zhXwmb2Kz+@`;htHU@xo@rsPgmVTZaWhj{?t)CdAFBhm-s8(1L)fHA~D0LCy~GHG2y zV(tHMrlT3A%`gC_D;+3ve8~@IppZxBF6eGIOfW&>(lkg^oF*Cn{)(GqLl6sR&(x{X->(tE#ZHu|V+SJ_9(%RkD-qYFL z*JHEy4-F2C3=K_;j7*JA%uYm4+`jd!cjIaI z+T*U(M;*%``9bUaz2@1yrkR_>8;|Ych^Mu$se2c2xDz4I)-;4x3SuXuO;mF`47y@(CnhpT zf#55K&z$u@1crd|G3rLUsPF`mVZ*^!rk6-mJf5h$iintUADU=%X^q7a0UEAvUn4@fHmz~Onk$YN=9g)*M4O{y`b)|t}#oGecm(r%Zu4gKtc)(WO+YQ`xHIN-0QADiP2m$7WTLg$CHpK@HDhZ&FxX zYItl?cuag)bX-_eba*7DtimJ0LLgx`q%;E(l`=(T*`QZaSs<+{lvNeW*rjrArLvXz*JD>-jzCvl6J35Yc=`3f?koGwOWWp)-i_zoYfrmY zpLDJ~ZeMx`j4h5k#8gaPK{UqsjyQ@g2TpeNmJwtpkSIojG0iZeoOp@P497ANhruwW z^$Ek&N=$UcV2ufk1U7zS?IAX9!3<+k8$mcTJqHI8Fb?BXNZM>D zAxjK1;^`fnoSH3`YUN6!NTR6|$T53WSi(+D%ZX3Uz|U?^|BwsrK4hE(t@tR(p`zjL zk06XX1riY?dzM`4$6&)hM3l;6D>aE6V>-V%L)4lfX=6y+ney&zl?}>K_vLE(p?o~? zTV-#yq9<40ku7V@5?h!;!ZU+sNatwM*orikG_^vQSW=fz$caamCc7dsvm`PjKPEjl zDkT$Z?!x2KBI1%^cp_qABch^kBXv|{XiP+KbVNWxL||f6U{Yj2QiR`^OEd_*P-e7W zP8<35k?fTfCDUE*7}ijgCacR*H03GU ziZoqin!YMSUzHANS)ZRk8f|Q}l$8ufRzV~wXF}47Old{7tRh!dm9JnIDmX<-PN}N4 zLd|Du1zeqohX~vtmzvdzMyoce=~FAr`el7J8u0tLuum1 zFXOk~j^F%s^v2tfYj20I{xWdot^M*ZP~Xl^y<4w)H(vIvzvxZ83_z-_`*o|2gF50ro_eL!UD_*qD>+*Ej=ta6eC4cY2y;<3L}kSm#7LIn#8a{ zh`h!NAbsJIPk2-kxW%{%guyEe50+NcV53n|YIaBz4pZTmyr}6^7x!ZqJWx|U>m7`8 z264jCOpk;D-?WN=EM8am;71*S2muwlFiGEEd4 z#|!nNg@%y=tvyd;%Tx7a17>L(fteziQLD+|DpOd}6J3Gu%$Od@c>XNCc=raTqWR-{t&rW;rpMmB?}I-Q7mt*>Sn zI81$YCZuK&DXNHMm09wtY)HY%QL+kD>_Qc%SW{D~sjbk|Rp|vB0Bn>B5rGN7IyF2n z4KN~bS4T&8cQ*|1fPD}Kcz9$226%MRF)_U~F}pfFw>iDAJ-c*eZsi&PUfA55*}gM_ z*t?6^`)Ka!Q^&Puj%&|nu05Z={%YpNYXCfb>t~wY>07@;6Sseb#&7)wjokQS`1kJ1tnG02RiC}>y1-VA>q zKWv=>!{nBPuNXc=mk!7%{NWuB?_dPpda+ueZV)0A*DEl}or~o~%!0^x9HwI2eX*9) z7x&|wyyT5?@J0V{*I>#C$LIK_mIh>ULi2^u<*I~gLn_~rA#TrA_UG${@`0#nthjNq z#4=lMov&zHsBB+kL2b({>rz$gVr9!hMbk`K<7BC6q}VW2tQ#oM*z)CFd6Kp~u_d?O zoL#5StWjlD%hRjG$z_71VqQuCJ2|&JDXRoK?h+Y!@flf(X^e!F)P$s@#H57egqWoG zsMPofC@nrLJuW0GAuRjLRT{W-AU`n#tKF&X?$mm~w9tx-a719x%gMqlQuJXE2E)?A zB*b9=4CyML1Wyz^Kt72#2PMKDS|Z-U>JS5Uo#9xjqrQ) z1TGZ2h~5djKpznzJe&icasyv9zLtlZN0RGg#|y#vEsy#vVF7I#0i=(wT! z5Sr+P5$wc*fQ$;{(BLBC+4_{aW`?*cOWB7QTWp>vZJsG>oddU3U2E07o2=eVZr?W7 zwo_}{sp;LW?cS>C+N|za1=5u*bLGvm1ZLwHNG{g&6)Sp*743!MmOP5&tQt)QTfwL# z9jc6CF4+c_TTYhUWfdkfa#9#ssp%PHPZMrsNRDSD$1##)m`Tyh#E9JF$o%ARy3f2Y zIlPc+*+t(Y`gpNZ0svPsBG}9b8enuv&@SS$4F%2VMS3@io>FimU|H>yQR6y+S=3JL24L%eRjKjcxYsFd}4fJW@377a&{2_&n#@t zEN#O8&#jXPytsLLW&7Up?xTgvPZq8|UAp#S@%qcfTdx;y{m>EqcwB)-R%8$Gtj;FllR_@?R^-%{eI-u`{A4K{tL#Gqv%?BjKf{a;{8U) zo^j%;c4P;ZSYcZx$2y8(l3tTrFaeE~6pXTZFdV}uM`kH7D#J4{&c!q2tP7T5UILR~ z7(o~*HLOFy^c;e4LR55mViL-8c^QnNoLnq^!9rTxQ-*+z(;Sv(e$6n@Mc}0wCfhYn zUjoB;hJ?qLRo2RsMohnoq*{bxtcAgPt`uf|R6=?{SS;!bSoeL-GXRS(+=FA?!;?K@ z7``b*s8)m)2x2N#DYfP_p*2(9m!lglHWPZw+m|c4*4VZ!j{S1Y;MLlpYjs1{`NKEs zhi(c6Z`2Q5=MP-3?YqM6-C=icvO3nPtV5tyWc;em;NfcyQod7vXO0k}5P!pmx+Rh!ey z%WbTq#LH`}%Qy21Oi*nhWaJf_>Pi~;r9^@%b3Mx}Lyrsk(+7iZ?y919zcrESN`?!wx&g^gQ_ z8+%LJcUN}rFI{=Oc=b8L@8b2>%Qt^oy7lw&t+$J}-!AO^y14hp;@v+N?!I5V_hJ6t zN5}!)|1kIPg9Cc-ar(iBiMyZ1?|dBDBO1K<&i*AD!x;B$zQW16S%sZt%zU>L>0BrtXQR?u(}%NT(hVO+FM) zJP?fEs~f$;8@$D}U*+^&=5%ke+g4#Ssw@sx<5Z<_q)a0%vhZ_= z>hfCn`B1YUznNbEHSvoeb6s&Gzr-vkYpgGC5>_;eDw{;rO%kp}T4#~-TNT1qmDsA4 zTlLCzla2*`kzxy)|cRlORkf5L$ZkW2R zrx-?Rf=;jTOg65z6I1-yse(Tp(({v5fprsPNIxvu-8TY7y0aHN!7#bE^fYeUC3Out z2**dl{v|L|(Ib&rkeP!Qks)EYTl^$7#SAlyIQ(B2#=U%JUC3PtC(e?&3FQz~gK6Piov z424{ELA5-;N|ay0%P-@Sb&mO^WKCXn4)%v&2?H)jEn=jWWF})W0`2AK(M6{&dL2pI zSXMk*7r3~RAUBSzxWq;XEJdNF;ShUi^8kS1AB=2*E(E&^(Xkikw(@hVf?TMrKCfMv z-(Fv6rPL-YY84hkEy7aBA}oi1u0>qcB4M>k*{!nLRz+Q#QrM;zwW}o^I(es2-Pxe+ zZZdUS8hfqQ{*DfNcMkv_u_K9wBi!WV#LV>cg2S=wm|tI5+FDwFq$XP35+WsahDURYxoDi2`9y(HkXVbjQQpK z%)G?t1V0a7TpfPuJ# zj&)A|72e1#{^VVu;}PgptiDli{G!=>tK0rfzw^6cn@GR)n||we_2zHN^|!K>U!;q# zq>ks3na9HMJA#p0!lCQ+{a5OG3CXpsOCY(*I8mV=s#Nw=$lJ=qmJ)#p|H&8Es0!JV zB9@?_lv7yD!UE62yn^D~ypo(8Ed0bBsTk_1%t@=tO0CRHVL@5R=oy1*^ODiMfPMzD zqm}B?K{XkId4K>g5@i&?nV;QnZB7#vdue(z{CVk zPfs~!XP4&ZR{`+i$_@c|^ZL^Et>vA&tCt_FUi}R4`pp;Xw_dO9y&nZkv5K~;w7d!naEeRVMMdm_9L)7p=V!9>8Js*uO@2mgei~F)kc#dF z^fQpXtkkp-JyitrKp)=#FzCfe4d_B&N8K)ALAR)|M?%ykDIyY=bW2J*C8b@`vJPoE z)Gn>;kX3a^S?w}*hn&-?;6fb=UZ=XgQzPlp$$JdSZlk)#tm|uP=xc2nXlotlY#Zw7 z8Sd*x1O~v9V-wR8Q!~?ZGc${GjyHlB9y?bkEj@8Ui_l}|{8L&7b5Dq79y%u< zIw$Ts$L>3a?|d4h?8G6%-J8!l*PmJ!?=?GaH%whUWLVNpY8+sgqq1VLRRLF-MUoQi znDpX^#2hpUcn3whdIi%A<2FbzjLHRqFq#D5gppE15JsmZ00zdmh}q94=*+1LCs2hx zO^>}(C%Drtm?!;A^55vCsYY8ej()hd3|ndugr!Oyp2)MYIik|?TI>u@NX-e0O$&%5 z*F1Ser1-=#(KZ>J%|=s10!N=FYRysG3yhPcZ5w5_tK8AM!nvoi+D7~Iq?T)SnG&zv|_6lNvzXF(;2hfYd8tg6t zFCBY3L=?c{qFyOckF119TGlHohkE1{J@U#fNXF_?u)E~d-3m^ZvZh;A+oR@nsrcPm zQMXP8fNdtV&8)LE8TwnB>}?hRJlNemWa}HHBJkAcI1R7^0MD%ufS0%7B9=F>} z+1*>cd}x4)g;=}&dVTNB+TPEIz^iwOg`gww`r~~7yb3*WEh*$?jKjtlN6=HN(cy9sST68rY=mlOoGdt-h;T*;-a_z<~}Y zZZc1YUGcc=AR^HxDALU{(8bLgH=ZNkdkOcQySd>Ky)Y~WjEGFe_-Aqo7zV(MR3-dc91mxo8ha?;79Y|2%aEFX>4Nq3ZuForG zr!otpaRoyxx!}n+Ivwr4NJ`KQ$8q%OVr!muu+ThH-n~;ba8oe-ShhqWu=etwpts@9 zr^fsHmd6LJPn~Vgo$b$@?avRoo;xADz?+uG`z?YwJ$+Z2G zVeO@M>8ToqgpSGf%k@3$g3e`-Tx}j_8wOaK9(1mfonZAkR-KAfBW6_#(8cx6R(XfH3xg-E+XX_mMwQ(VSSlryoH_45uN7DLA(WsAeJ8xC%*b$N6I zhUo>ph`>D*y*61f)F&_LmzP0yMP;9&vR_$cQ&#n<*u9XFV^eW^RW&wsZLg-zrsenP z1U8+h*C^{XDf`V@d!x?YY_zvD47Rrnby|meI!A0a06Z}?41lM`CmmCBj@gBUxs`?a z4FJ5dc6oLE+UnMgjh#IN;dMk{DhLyRZ@pQ){nPrLUsmt@x_+@gc()6csiP zaAFT{S_YhO zb_NqcI4A(iExnE%J@+HhWv5(_Mnee$TPeO~7;pZ!Ledytj3+MOLpnk%)6t1ye!YrY zE5*)mgyO^uwBKZf#4`P3Nv9>6enWDq!%M_*97CG89Tkm|=D8}{70&QI(cE*mTs;MF zBVz9(r{$^B`qJ6?#@YR|vlsfs+5d~v_SV_+v$ON3gZ5Vk9WVF0Uha21`_%sEgZ05X z%ibTBo4+?-ecQD2i)rIE!ZPhHq{G)G1G^xZ*S1h&ndCMMW26fwVytT9h>g|tDzaRc zN3LnWbvd={YJOFfu&M&HX=pF6uP72#6rxu_Qk6$)zLi<(s%$kD3$wHI)!ByXOo%?a z(c#z1&ue1vIE)K?7eY@Vf6er|s8+zPJ0mKkfIt{MhyE zW9Q=!oe$o(-+SM7>rczI-y3#*)~~+QEId`tJWx*TNrtY~+cx=~3%u6py2fE7C;7V0 zI#p|(tbr#cbw(^K#UdQ6(Gzhv7>f|ItH^u=t5nJ=k+F(o>;lw$mF!$CJ6BhoYvAOV zIJstSHbm2l@Jr~eCxnn1)&#hT58jIxJ&79iz7HNxOY=aBym5bOw2}$!W** z?3`n9aefs5uPpDbu3cTT(KL$yp`vIl;+! zfhmPSsKVsdl0F}R7`Xq7f|z8rE^4A$=`0psO3y^M?%e!zR&)Nit@ZjW)?gnp8v0`r#JS zu+==;-Za|TGTPlfY3rG=+h&G_rbb6*$0r<cMrqt79UdHn zR$mF*PU031!Z5wr>}!VUVEgwc%rIgy-pA9+Hx!{5 z=jaoj_H^5f_!!X5?4KXO@Pi7h&Kcgjt2;@Yf8ZFvl6VQ8)2evGSAg>U+zb zgSN-cj+ewg*#2<#zjqFSTPMXW&~+Y+Iu9nC&T;3#7`wxS@8`P&;PijTq~oQDgmxNjTad z9&eORG$|&Vl~WegWQ%sp+A!AEINsSZ(bYQ9-7(qMJ!9{i9iPFOBPtY8muMYmg@Z@9XIPAnD=g2+h z;NHId<~!T9-}^5A(!KS%W9^A`>tKz6tv=Ck{3Z345RdhtEEE%{4uYAHp{d`vW*I@5eUK=$*G}%VV5p?oH$M*FaU;r z#Na%&m+$)%7k{AicW%Fa2OES?twS`%3*@3>;?og|VTR>Ovq)yF7il>>c}bNZtGF6h z??o|7!x&|unXIt{b}93SA>IgbJlrC6Q{yVy#f9spqQ&wWQ0DUyXJJ zlb{0SvnD~QMNrxzC?TpZY7-V80u28Efcuo?pB*o30|oFf6@EeQxRGem#GNqKOc;5S zraEY%fj`zDfW{j{V`d8AW;y7cY1PbHwNq_|iT1|HPRn$cb-K5Gs<&&}-s>2&J4S~V z#ySuoKkgeZU|lg)A}0&5U~XW9%i9VWtXSMyAdb;i~{ z)892SV4E8npc$T#N%&2yfnkh1lM?w|)5m0N%d-bo<5&7>S)b zKX2XnW&7T*2*O(r-oplOQ8pM6c!Lrheh-82`Wq*-LW!XJ+DSW#&kQ3kap)ze+}iM+ zgTdRMV1~gkF~b`#NwdVlUD5+Twu>PS%!G;%gv|q3E`dEi*esF9ks_-GBN3gN8x);_ z-9EU8+}+FH-O~#j6%d32JbfbkgA&6capieVa#~($25x*T$|+1w&hYmQ#tt8}wEYFn zufyzLKKlD_X>{rLk=8hK&OI_Zxww>DFVTZxs7`EP^VKEQk}Ujt7II?qsv~l%BMJz^ zsBxg<9nF*IK;w<ZT$O)3C_bGjHPJVKZQ|@B$w@(9aKjFmJ`SfGkgLf3hzna!w8|I%G zryuFZZtDjx>v~u9U9FvWjk5xlMsw8416Kffuot1YScm0G==rfN6#a#tk*o=Gy57-i*0! zrm=pyNjTjonrsq{Hv(YUp@o>X>ZjX{Gu`IdF3W6B>s(*QoV{y)pvN&}TNoLdA0Jr& zz%#SUj-{1_RRFxQvIT%)g8}f?_T9~$ds|l@(k^1>=F81nuK_TE@aDbWsUS=k-h7NS z+9&D|w+{n+$S?`QuoG{bYp?&!@MlZ>@^fBd?y1v3#o_UXBsq-4+Rz>jbRYYPk$8(j zbLZM~(zG_WhXH59$Tr<3K?h+n3My%!HvEXtQkZ}fQ*u^dR5D5%FvD)1zF-&;*w@1= z$lEU}Fa&cr%$TISq>O^JtRiM!c6wH9WW2k(FDe??;`?_p|KHysxwtPO8kr5e#`lbl zO=s6gc_LtJ;EA-zT(Ja7Tx3Rkdtq%{K`mxEW6PwNn@g*=pqss-b?%U16yT7N=={lP zd+)RphWAID?FK!Y?#yu7PG6dC+Vl-_ay+G>c}MMYGM4X$t{(xRlS{TNt%3kB=@*jW5s4uFTD^Ev&9DQxSN5cXQ(!T*TJS z-eC~lz5aCP*7M7^UvJ%h1BSQmzCC1^1mQ0X17MnAnqK+|fN6%8zY4+&Ul<0!5MAQ{ zz$kDKfN#8~g7D91T5Df@jLu;UI5&)4!FWEFR$&AQV|19^Alp%d2CS%Jl=CSgQ4pTM z@Q+CJ3W`MAxvPf{820w?3h?#~^ACy-i)2J6X2+-ICNqi|xdj=1niT1!Uz_R@KPK9Xb*{eH&Cots<*}kEP!UMRl>og1B-irsptx zRH*4k4{(kBhG6Cix*)!e!+oD%B)~9?#Cr$D@alnc^OJM?lXK(1x#8TWweAGZPJBdQ zJ|J441d<*5&e>0d(0COtG~8w{oK0x+`90vW$H%L=$2)0 zxw+o~j2qhRO)cF`O>J1LXU1Yvqt2pNTXiz47A-gYc2#YssJ6a@jEwb5G z*-Wc))~a%}>E_z?jt_VPqr@0S3c#5T?^>RE>iGJPR|7BHjIc0F2Bq7)EsiO>1;U!n*tr6C7yuF^y~^ zEsUvr(j#H)N1sm_dL(!nq}0->ARL*T4I|+l5{oWJ^qga$7@MYiy?jFa1EWL2lcQoY zDS-1*m(`?%=Z|VU`%&0FnJveB8?d(PR_j5Yp zBaFnH^V2ecmH@o_$$90#dBu4E?Gib+oz6`ssCKUGQ!s;P3g-EJCj^Xf;v?1q82_?A z_-eoZ@yG5ve{|pYtz+j+``UBs{5@dYGPVtj$!6WIv8FaVc9}L?+L{`hF&}{`2{bxd z_0o2&utUf1*3@-rPzC-ho2F(^S3^={`sxt_XVl1rs3Tj=WCIaw0|~rMwX@AUhough zvk2x}2*3+1qJ>uJyj3>eDtB1rjyCmNyJo(_u+VAz-_*SaTU+Py_WOa}f7wagTjC^6 z9QOt`z4zXG?;X*F5D1|z)GLwz(L1=}-g`?N$8j7RX`TC73oFEiY}?5`?>YOLt!r5b zLBvm^d1mgJ8B=tREBO-|;e=j1u9Hs~71L(Tv_&^%HB9yQ%?$R>3=htZLenz=hUaEa zzQZsg;WLYO;e^jzdJHFg_S!QrdV>&oCu9fDK2j$*$LVkm(+5w zSu&}pJ|@2|GPe$G_2ETrXtz&kQs7vZuUaUzU2mHG2@Eswu;vwsCFqpe(jfH)q3A85>rxC^!k{qYEMGG!Qd%VnqgbXAV!nt_DCT!bc^$H@RymiY;MS`; z>eQTSReP1D9p&Ik9j5}R-M)@8hF)t|84L^$;Ka13mji$&6kPy#QZ1O$iKh%QFg$5ePMS3{R>QOvPS`SQADA8<2E(%x zQzVd>JvsZ<4=*64M(5K`E#Adx4w3NbD^F=B{A@XpxbYhbbEK?%k2qnJ~g{wijr2= zij-PpdT~fX4xBI)HPGndG`IVJ+wOgbF-Kc*la;VL_uRjL2E<_H?dxt#x`b2ri#oL8zvvNpZgUW3F3#58D93oPCI>eo2Q(o zfUbkO=%6k;sjHOpDur8OmtjuoB1K&QBH7&vqvR?=UchohIQbRfdx_5lK^$c9Vpel?;q35FXqkFEHtwbaYCyYoKPB=6% zH!v#QBQW|XwB>Hzs4t^Dhw27)5F9_|?&s+pg2Povczi^3a#UbRYpH$=r#x;rx&(h8E{w_ymF>2sfBoN^319Yae_U~GBrF#qHQ&fP(64p}vnHo!2Q7Je~zgNTG@ zZ~qQ?FjPHr_o!LM4?iI4h~+?n26*z(9{`gmf@T;16T9am%Hi7%hGF#60br!m05GBm z%$I;e5D#DJ=_f}yIN_#VJC+)hbG1dSQbfXV!lbyIQ4$=J=@*`O!Y};D3BQ9!Pk`Zl zhupA!3+oQygaf>N!vce2!y*$RV-llclcM9If+LO{IErqg?b|TupO6NCF~jOZKwaxG zD?RX^ufJ#XY>_c3CFS*1thP#4J9ea&)pK(yvBS3oJ8=?9IdN!qs}>|SD$=?KvU+FB z`>(am{n&+i#C;-@0K-NHWp+C3)Eh7i8qb1HIN>)0-CIs4>^4Q+brQn`>?TD>hG%Ac zGMI-gP|jJ(F-v#Q?U)AS+Qp`QV5l=F788f0W z^IT>ehBua~fU!z0mG+7S8Zl2TSC6_kdl&Tv5&*;Q61}PYx zu^@`j&-I(;2K$H;9v+w{PI!D_a%N$AmiS==5_5|Sr!L|^2Z7AVHgtzkJ1c--oXdXp$AU; zou#4MZ|pbU3|#*mP8fa7jKT*1Gx;<`5j}$#7`T8ixLGlT#T+%=IpNpeyTWjGMcP>NuH|t=JbCU)mN^!j3QROsJEjaQiYO6J_QL zjgt?#i@!1W}dhX#_k5xCV;NXz%T%I837pi2ZRvt!0^M8 zIs&kaMF4)w@N_TxeTHZC5->bt>SY*)6JBO`Xb=p~j!%GLS5|Fq;XGmZ^c9BT*>kt& z&fS|k|6t)F$qa*G=!7A&oJN=2^;grkUQgXxnxxw_pmHZ7VOnF!$SjFajW$N5=JLRx zci_Hb@ZQqk?Kgure+R&}tH1SKMgtwGEF%}eL=j}t+7O0bp6)cww5dr!AG(zC4khMD zV2Lx1a>%Deq!hpj17NgBpy`r0;X}t@hmW|s9Xr895mCWmaKiAwD9J^KMPR?izTNx3 z-ifN*ml*g1fDs9U;SY@^KJwfLpNz$|Fi4MrLZhj$vevmnh4xPRq|u^Am^Z-W%ifSL*Y> z$QQ_g8q;)@!)N9F^AhuzOg|vg_Q^4{OrcQAC0bdJUfg96agD+bld#>?(`N2zvi7iS zJ)}s1S{nd{4GQY)!unxREo?+w2OAgH!zQG}2*7gUglFVUGjPJatuBVARGkQhr`7yv ztq2Uy8fApxJ}pjjh=k_`taJ8(`C&W5@X0CSgh_1_q}Lm;tm<{I6v@dv|1sCMNi zqIJLif?*iVo^KhZ8#L}ZCtysc27S9ynFe7GY~a4L|DMBkcd7sO8{75Y`>(ySUU}Jf z=>-O)pzVkxBIX{EFnIi?(0&O~1ka2i@Dq*l!FrJy07L7Jo+GSm#?Eo9Ktg31)9{XA zJgG+@q{92@5CQ;W0fDE77sBAkpwO7m2ogoa#KlHL1^WgaKYHRDw8(AyiY(ULPU44U zfIsX^hurU~w$^zN3~$={)w+$_u+a0sVRytb=uRrDX{u`Al(9I4b=;il4l@0_f|FXs zOQ{oMyboM)o_xB(atW@u&@S-Zvi%4cn*M3k^{i9>H7p= zL=m<{0E~ScZCJx0GLtBR)>sn9MQhzd;&YdE!T{La=irg!2q6v}L=@}>fc?CEk&AFS zVQAeE6}ugF$C9J1pcl(wF*$JiP9}W}4X{aR!xV`h8fJQl6Q1pD zo&~^4HW;2(ai-N>wDG|(f?*fKvliVS83~%6XvYyA*7UuE8M# z3`x%*@(*{M*4s;#TW|VqzP2C+zVgy~@rCjH&-!ye0bqm>(y4o*aZ=Gh<7XF!W&>c= z7*^B);K~j%K>~m7w^LAx(0z}dh@;-27;=tC7+#J5j0w?h$9=tgFg=(691@Ng7=Z-D zX$UR$VngEAFTpTbrupSJWVAIM2{Y5JKM>cCdl;R#!_NZ7c-QRSOCpMloWi1VR%so( zs;RrAfuC2?l~di7Ro#tACP^$Zs49~;fZ0A}mdmW^hg@`IJX}&jJp6_z)<#KXd1=A< z<~-$K7-n2C!Ui~AIAH+%ql5a1a>79JN{nw(4jl9lRKSNLqQ((#ngrNT4H2bKKLX=d z)BrGkN?GnNnQp!^UU`8Lj(QB##i0I?a|$d2vW%)s0~)0pKA~0{~u?VE_yx0QWWm;5kLh8~|3bXO$d=;Ta7HBxbb&1QPQ` z*}S=Tu1^Vur&ngxhKCu3QQd%0ZFcH3dX5;iFy!vD=v+QcTJOOyy6-0!A28!1Fn$V? zPcXM^xPgYvFG}0*yt^X%Z6_|M(#LKynqedcEI{?E!l1odQI0~8L$0jy7JO| z@fXYq)SdkipIPw009Y`Ja>g}YKS`#M%>~L)Y^JO0F;sAR5k;VTF}<8kDqI++7Ml$x zjLzl5Copc^=g=_^_+dH>c83!Nz-YQp!1z?8Bf_JAacDpg8KH(=`z<>#yA@L-w(a~D z4C5#VjKMIr415TjC?c4ZZ_*zf>X(jwqJkg{&r!dhrIz4P z5g{0bADxb$-!lA|az3P%?o&&5sU_l#amu5Ua*L>g(AhR5jiIan#t2l9rWkrf z4L+v^o;a;{mn=74na@ANSY7?>EzQJ5&Cn@L|CF|GSZ}f!bUK4tVOB`{aOrO0sb?*M;;zN1})zh&H zPscC+JVNXj%>5g>^4lQn>MPjL_17*#wt*xZXtUmU4Kv^PouL=m8_lI(G#8)4{pwFY zg(8AvA!vZR2d{M6F1DLax9R4Zl;bSyj_EO@Z5b+eB-7H%+b}*NGOa8iHrFdO8RH|c zYh(X0pZ!O?4jh4~=fp8L4*(qC=NBFn92FXdY%mx`c`np1(9`Ys58v(Hx&7-M@WA9K z_bnOBzMU+{z<72rjCDn;!uf%BuFf!=Fv1o3U4yAXc<*4d%&y)0(Q}8Y2js*hHSJ~S zVyi`tqC3B~JF|+HUMo&(P-LLk!5>D=u6*!X!>Om7YrhH~FZKT7uq+YSCMd@&_2x7k zP9Veu#&E^U3{wQ)XHLg+r}JmZLAzqdW6Hr`42F@%AUQXbNN86Kj3Kc=(ik=db5J9% zsi9w~!Dp29;T!9n*L|1aXMQ5%&8M!bN6)G4b6VTD-ZF$a>SU0PQVERBy%LK|U_oz% zggYo<4@q0?k`^d-28B()7~%&2{D&)E!7w6<8H5mToiO|`127_C;)FFM7@pA!nLuKp zPcdszF@AXYKxZFXpc%&42&jE#CJ4hb(}ZEP&Y|;Y`sCH=)3?b8lrwiH&)%Cp_i&1y zLj{J%FaYqr>ThP+;Cl_1Ug$17 zSDk-`B&6o_6O0UR_}kUc{-_#Q<)qDTk#;>UCXRuySV;xf)`?1dgQ>nFzUV~h2 zl!}dFL7$js5pisy_I@GTCTtlHx-cfeFv&&Gr#U7bo{%-ekc)sJ5}xg)BVi?XhMeZQ z0PvKyXHqACMqh!5w6Q^!Zp1M16`rg#pN0a9sPcA+gKmTOx{Es6SejL8=GcX>x^kVq( zuP|V2y+nrot*}@0H5q7$yqV!V=Cb~Rvl|&db?Px%gKZ>sE6m$k{4hfo!>qOwauQnG!ck~~79j`#!|a65q=aM&t~Q{0gwN8FDc^Y%oK z25Gm)Zp4Vt@QCo}kl=7H55GNo4{qQ7&8AH|wroKZvFjb!5KA!ktP1A`-ucdRy8h_` z7#DAU3hCm<)C=!`$i(y_L=^DGrL~;WI&NuwcWxEDu`rz_&uG`D^9QpOGX?#ZD`y|J zTz<*B=RlIp1i+wvrzlh_<|stPq#lO^1;_-$2!O#Y0Deg=!GQ74)RK$gdxT*J9?2x! z06zlb^A1v#J`D-n5;eC(FrIi#4Zoyp&mGn$jx_ zdtrY5$_$19F5DPfxH-OXd+g+$iPI0p&paGI`)Kssqmgq@h8CaL7k?T&|C9av&x049 z+b{lNyZ8bOn=ZY9884z>0d$wmbpC~L@fS>;0=@dvKWXXtY0MZvl7gT$Y0Cg>Cvk{t z5Zmen#%it_9=MoHvm}!M(WViWmKzwK>Kz_^JSgOtm+wJ(xsMzEcN730MWdX*w^wLD zAf^X{;YeiCf+Ib=1E7S*ntPy#92ahpC~yJx&cz4fy6VH;c`DaG*J60XR!kmp^9_zm z&Me65>0Xcq4Senc z<7ub!G)2LeG8mI^f_A*mX?kftOc;hMMmX_^a)RNvISMA*M$UJrl`Jz1H8SmrArKmQ zMfJaM*q*-Wzw3ky0Ipbn<_VVms3)&zM$YQ&^J>ee);y@w_36}FGT*GX*C>;ir6M$J zT1A~U5$An|f$_2*mNtz`o0k1B%`gC7m0?D!#xOi(>V+Sk?bEv$o*T5!4-dN-o*SQ= z9X~ZYd1iKcafV=gX?pI;_}sOTx$C3zH?US?bm8{MsXHU5?qjWn{q)0uGY|XEJh7d9 z(tq|x+qs|m7oYVl{)`+i2K~V>pU1RF+go}e;L)D^V@Uz}GKj2wtV+_Cn zKHeb#{$LovFlrfCwd~~;fG~p=E$rC1gbFnI%fAdbnz%FB+3JrI# z&o+FCx(9~J`h{Q~TRAW;u4d;~vGZy>vuk*1wSv?J8CDe}aLj4ai9ExZ^5N^OQxAJ? z{ib+I8DEkd!Z6Nv4tQheEm66EM@3Xj(rAyUr5~v`Ko=y#RxMo1{q`Gis>re zGQ-fhy=8bDPyRbK@aq!7iNS|N7K>=maQ-K3OVQ3;*N&gpjhs~5CULma8Z6impjW94 z3amPol5r(sUZ1Fwam9!zT;T*%!8F5-z!(7k1;dldPWWMznBj-PFk}*w1_}Hy7@jh# zp!S)vn5M0L)BV=jfx)?PhROxvUPKP?z07_M6fueW9k>X9$^JzBEC9v;z*?ad0Hc%)_Ou0z_?h+@cJ#^e6eXK8cu(J+&Mf6!zU3`6jZk6)pbDCpHbJ1@z;qg z8P*x3blI|GQ$?n8HRCrp=YJC3d8Pc3GQFa#sIQTd2kGNLmh2qmxJ)e}dxjJQFn&V4 z0m(lSo|lj)Cb?o%@yOwhJm3zsbcBMDXe^_MigB=mE7mF%TDb%>qYzFYLBY7<_ZcQh38*V+ zhR0+rFsLJ7EB)|03?rNX!w8ANFjSXs88$NvPuuO&L!*;JqthePQMuw24}7U1M}ChpUb*%6Z^TanXB*QJuK%koqCA3C)sCo`mv72 zl_nO4wI^6ZKrhsI0QHU%1B54U6H(v94RjTe8r;AIY))jB9JQ(@8f3!&7{fXMFyn!< zP`WB=jLWV@6D8)SL0Sn_&oR${gKhx$_`$AqA|C+ zEvuTHQOixQ=VKp1LcJ7o*fP2Y@|4r%mc^!-d)$jZi|)S0xCuQ(4o;HS9j7a93zWl! zG16#AM9?HJ1B|3GQ@^7zUb^R`F{bNxgkf3;M;LyqnIA}q|VMy(|)1A65;_+e=eNl?&-JA@OilN||(MFilr7=}gy z@i25gOgucH?uL!41uljsjYK&Nh9~=sXy1VP9UUA~gM;WoLO=e*$RwuvU^XBIv|`E8 z==dq@DZru)EII0*zBDj>#WuaXClN~$`{u5j=Wdx6Zkw15iSze#3-@7~llSR;Mhv$k z+W@Z%bTPsm^a5S!=rxGYT=b$T19D1Q57=%FUw|>2D^Ve|57-WGIcX&){YF>F}MMHX3 zV^&RDCYrTtdCArMaz;_kL3~ramC$8P@v?2lif;&fiZeCU{JZk z#-wd9#t##b&z~6{SMgj7FQ+DG;U)6JXhE8=n!xZ>zZDEm+K0yM!HW*lKk#j5K`*qF9Bi#c38UAJWdw*H(3e3PJnQ((K7yqD+UT^Bu=t#S z$TY8Dw8({_mT~ylAH_H~=qiu7Vbgu6uWwXPP)tZjTv#{^0Hbwo->yAh!S`0w-+_zc-XX}gWt7%tRMclx zH|N&2<1m|6#YM(Avssj%~hUw}vVSbrmq@CX~jH(ARcyPr7KU22HRNsBdeDk&8@-H~q zspoFtWTzcHhm#$0#W>laY=`Qz3a(fwGtjOWQL$Ov*+*w57>toF{9y4uMmOlhpnc3f1cou33WKt-EpcdMj@j5XICc^Xm;1&SEfeQq=J5;W$&1Fx zi+bEnU(rur(N15}Okcx>WyM<~3u@8HGD_Cef?LthWwHGdwug)C7X$-~0^3=h!u&EFa0ihNap`wP!$4W)IJa!Pdc3tx-+UaRHBhayF;gr?>ne_OVm9F^?-sc zXD9GgB;{}zTqLms(Q}x0<4XJl5YV0Sq z)=7jDNU~{kdPWF@Ilu@fjM8q1D9j>GpNQQrY9$#qaSLoj+%hU@Wjyehggq`}PxR7i zVK`xBI~_>S2Rb!z!Z_0{OW$eH+8jh{M$*naZq|BcR_32WbYzh$g{fXt^F9L1<% z%zMYuPqKAxc$QvVJ8vC5Z5cZQGmo7yjV~I<7Y!2^bQ2dyI5cryIetMgaX~(QNj7#- zI(k7mdQmodMLcpD!f9~JpeyV@*JC}^-M0YsPM2{O`Uj47vQ;&L`UMhb$N*Q-YX}fO zV2V592Z(u4#ekwRBrYQ$GTApI)&l^$`|LeTl4bv$=z^Jx1o)v74q=ROnQyZ5+k?f zqy?EIM+b(HtQ&I@hL@|)n0)m!WqCrG?o$lI+H;s^ejnk4dgOv;=(O58r7;g_^fnbr zc4`eyb~>3D;RK^+gP0APOeQLZj$##trR@{)_T@lg4Td3Fo2JFXvk<@=m1sm7!%PXf zD<2WXqzw%Bj}VOQ!viDsfziRiu>t$!fPESyTZd-*h8Il3C(R?LV8)R%hS9V7(R26^ zL55H@a#lII*gLu?8#yl?UWAE;&WVT53kT1O1{Q&?i(a7HX_)EIO|@$#AOmjg9U>A4 zK_A4xs9%&Y(Qjotlss_1k!dApEDDNA^9_sl42Z-Ii(|+AAm%}15t`%RfsY(Gdi=;S z@8ceU-acUgfj}1k!wG}rATRHu`ws5HzKqQ~c5K|See;*7X#5GAHBt)y_A!5t;njZ! zgy?wM^_#Zi7H=-*8qWEWLm%<&SqHVaL|t-FR~@9|1Kcup<8AXD zY8=SRLH~oIGss8X82}?5Udb>dKw#K(`;Fo1OE64|9W%EzBbPMxGaBoxx^F~n7*OlX zWR*9<38@s>i8UB*9TByTire6UX=@*swv)a&1sgW;XNHMvSWWyeBOXS%dEOwOMKhgI z1y?*_(oE2(VwbXtfX6hC#G#VB9(|ZX1}i3{05@XN|P!?Xw2^JmMdG ze5mawmG)D;#7@iXrzQ5&BKs-fz-dAMDS_=Y-*U3sJkK-D!GJEjE=N7qt{R1YvRO9R zAhEE7CWz3861Yu<0$gql7xOAp3hU!@s<1RIG%lNQzgQ%M6WkGZF93}8WE9%aWq%k= z%7>47xt~CH1^~w3N&t+-h=?WNkg+3X=e8YN*CUDc)mPiT-n5=n<^C<7AM${e41etP zTF;Lto#7S_a3%c^=ltu7tyr-X9tnkJX>MUnc1c}+MQcHAC$_*OS9B&+^(5BIQ(El2MGih`tZHY4j?63wqHF zO*i!ur;Yw5q?(xn9T-Mff>>e@?ax0G8Jmk?qQ+c!q?x{>9lfj_I;*wKsm)^=BSPXn zm0Hg*td)v%5`k94!-!zW;}I2G1Z@LiB54~Ee+t9UUP8Jyr9TPzqDIArO^{@MYHz27=yvyNJ9qgLCv#WrrVP3Ub?#QLZ8{WIGB88y^*{d0=` zc?kREwgqYbg2*=CW1Zt$=DYg{xA3}9{KD%p^fKte@ix7smlQA9a_psrh9|p{YVZuphe5QXyl234qS3tPCryrzf$Up4ce|YbneV8|eF%j^<48S4uT2E|6j1Lco zD-QGX!-AOI-|X77e&eQfo6)NL<+fd$Hhwg~Yw-!RT(;I@*1CT!hM7|yj(bFk4>{A%=8)P;hxV{5Y`P9k|V4PATOsSWrx9AGH?WKyj zs{YHhlXsDDliq!!`4MA$$f!VIOu}P2QO1yrK4|nfqaMdJB{41h_~%Kc>lqVQ-ZBgs z8^bVjrn5a;jwOg6zCzk{wewH3)AzI^SGD#AU|1!SuE{Wl_K4bs#c;yy zjJ@NBCsf=?^>RGC(hoBX&+4Qz2HBKOL5BS3RpUnWgi$w+iI-;cFs#pJ@3Re>2Z6Dz zZ`f)Xv06s^ETcxtn4UJRbxdoS&{!r^mPv(WQjR7;Vl(2tX@PmV+cd>9PIeh4y7W_A z?F1YzTR8%HTV;byVq1gAjKXmpPlwuZdApo6Vh{mO2YNA*3+fVbDnKtf>(Q8u8R?jC z;^q^KjfBXdp~QyxVgJ5E`}g4g2O)`o_6!~vl{m5pCL%I1CK_A9Lj(K)FxGW#+qil2 zhD}7@zU8Yeo4?*n%3&Xe@md_Z0LH~ykNNofNf!yY-L!f8hK*Y{ZrVmN7+bKzbocso zJ2r3n`sgv=_{8kYg36rIx@?RuM$#B#&xQ|5b45)WVg4b5VjxyQPxyPDyv+JQx#g)pqu4LbOhr`gBBQ%7>pw((}>wRWVQ~P`v*(|Hj~|I z9{e^N7wg4AT&U_<2-e9F-eKrN(iwaa^Py7aGR-y75l!C|5Jmp&ssd8#55c zE4Hx&eFz(HYO82hAoL{%w}u{w*r5T&wo1r=v3CFfqX36Ne?Fn{Cjue?Fw+)?QE7-D zm~npxQEx*k*xenQ;~)cuCJm|{><0(Kks-lIukG3O-S$nJ*MGil^QJ90$05jEw_(R7 za$F)AiN9|v8UEPo)qXnO2s;2R<9op{uHlV|ZQTCN_T4)+ehZ8-${V>v?4nK0FH0?| z%C2g{Y)>pN%fM>6vhLI}erBaOoux_O*b_uEdDs~WrSYl9omZcW?!8hzeWQEfF#Wb< zeeHxhgqd3;B&ak*+T*^T_Jf>j7 z#+B{w`{5aMG}9q57@pBe7>0rI6c{ELYsL-QQN3YUZ?GH80|s-y(P}f;EQSFyOh0He zK+!RXw-|Ys=?4`$yIg0NY3x$1U8EioXomQjA)eaarLuDr1MTtwOs{R0^f!vE@VYp! z)plvCI#lG;)*?mRi?Rh0zo3^420<%aMnz~!Nl0QoX14o;B|u1t9Y$zOMskVlgxz;| z*KX{z--{>$F)#r3az7s6?SpnssL`;B3k=6bK-V6E0tdDfAOj1Aw`|;bPwn}bBX-9TBFSA-2RjZ0>v!shBiVSCJN3OLlJm6jaNqp;9#p5^F zYhZ$e5<0gf!sHl4m2YTuB^_fhHDy2xm&+J(8q4M&VtC?&e{uFbp^QjM+;-}(zt&&; zbtS`^{&VWSIi+EoFs!y@ z#` zhY=0%x8HsL{dc?f@86FQ0v?!DlY@f7L&9RC(3~6_85RMJB{qX&-RIT~8xaP7wf##h zu>}uAV2LJWI_bI^KcB)d9J|Z#{2yg_Pkof3SrsB@re*bub(`>WkyH$eNzN!J&&ATB zs%DHF%q?p!sB9~!XiqO?Csy*~YsINes;o|Pk!-xS?`-SjEzZfuyz|d{uDz1pr<6}9 z%`-~(oHD#1b1xAs+ul$%hZEN4Sh6@BHj3(BY0N;j-yE3rYW&Hmzfb9IQQB(`^~K*+ z=YGLFbJSkd6E}N@&Z`DaDf(vc(X7(im1;|`!ldlgE;B3^YefRRkZ%&8N2${$QtONwol$MjtBoq9Nue?+lxDfY1QW}RBAKB_YJ~B` z#!j(;E7Eg?#&&_BjjwCsX&XA#^&QF@wjA3@%A1A7tZrMv?;TQm6BT(pHUi} zl84+cIlG0%dH6>ld*<#zD#(}%@xy_`XgB*|&w(HIlBw4SBn}=tc-+m+*V`*3C@>-{ zEHWY{HYNcERWMrb(cOtZ_hx)3!<8|g#czRO=v@n*kAm=TK6tI)VfFjz{}6ndY}>kh z$M!D~W~|?^1%hWB4Wi@H(sN6SD;kO_nviqLD{p|*EvKAB7l@EkYkJZeD=U>P+y?!)Qr6z zc+7JrW^U^qJ9W1y%{5AO>5XFXrTo-Sm@5d;i+t>=Y>+hU%gvL$hLK+Fph9Jl$ql_S zwNfI*#$>HXq!sq)1l?fR)YI7~=;-h1fCR{nQP`3;Fgz@48h%(TIk%q7kihNGl!G%KEi3o4VJk?(I`6ux8PO6p2!$SEv!6<83AD z)%VKvxRuIvB8gTg*7S(Ae37P8pyBqY+q=~qo~o@&+1#OM;7IG+q}8p$szw1a^H6jn zMUTyW*~P5X+^UqU(uB0a=%noMxb&dNBy=%g_v>*lf437p=r4oB7xaGj!~XAo*aO>x z-5EH<9Xsaf>FMu_zKnqI(2%Hzh`3nf(&B@HBHZ1*ckezx%5bPAZ`!ds4{v#X|Eqr! z%a8i@_ka3d-9t0H35U~7Tfi`43^4rp`Ym`%V#h~7SS&Wu7L>CXjFGR%E@{B0TS7@o zTuEze87Ho)C#hLM_A3d8OAV(gZI@VMw_6vUaLzsNzVcFhYpM4Er9z7|NJfV#Mqgs0 zCT-aCp~F-+tXq0P8L-9UN2mIcLv{bP>h^2Z)g|S{*S+Un%1-?(oqvQGq^Q73?28iX zNgV2B`Z0u;a-~hKFiT~6nM8@5^-7UQBka)#_}JiS?CE@mVUl43#xi1H*ah%Aewe8^ zGq*07C)B)ACEu>%52<_XYJpuP8h|Oq{b~u>@THI%6*9d-hK;whLBF9;NR?8l3cr{{ zq7;i2JwgRv(97fZc6G}+T{1RT($XPqZI?8%MfJ^sDzX*|=ynuWwdYr~k@9sLJm6 z1{nser1NZ9l93|qe1-LV!|08+xd*&+&w4Ju5L|m9x&52s!IJWc6FlR#_vsQ07v!Et zPSpcP@7*`@n`FYa?9$8L3%~WA`xO9-=N^lv?})~(K{+7mKO;8JU=*7~HzZN_OBH4~ zVW~tT6)WUIkxD4U_GEQWw}#(k;B$?9uDOR}<8y3+wn5^G=|r)#mBIKOhM8~z=;Gpi z8&h^-k~XHn!v#$PI#g-4lyvDf`~~( z01+1#7!cy-<^_NO?Yeba*00|Rgh(OdBV*K0cs%I+H2b)pwRt-UiooxtEnpb21hK7O zVbBWBcffe(cLz`SgeIot=a4L4ItlDn6ZW4GS{6jc39)`utnL@X1IrB(nN}iJ z%S3W{k3iAWqvZ3H-CgSLPJMTWp}WJxZ?|^0gW&;!F`D;@D;|`#!VpWW3@6}?8HdbV zymLFM;12il7_%#Q_TKIRdC!1c&@UJCVOJe=8e)N7BG8EhY>uzc8Y-sAJXK`w3+bSxXO3GN+O`Ka)jh&dNF=4xFLRxNIVkQDP zOo|E)i$+obok7QrdmlP_{J?=@jQidF{a(Vqa`jY=;Z*&=)uxf#oaslM3qSGC{L+2ym!8F!f(tKk3llEB1iGTrzX?wM zDwumAnEAP9>Y;Gr4rV4`=m&r30!D}RnCCEIyGJ`LR1b)HO(MBoEY;v+S}c@Hdn7V` zkD|Lv!Ru7zEqy5_o?#>&e2(vsSOqN?2d^6b3g^sM}p^qj<$%-Dp~sHlYSh#2&>`3Hm` zwsmv�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 F5!Wx`1{m^IM0x@Fdn?jM1l?q!Wv=JpKx664 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�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

~DM2l$?YEE#QfMKvsoLa5- zs#16&@{5kctOO4qgfC2sCR@zc`UT1ZW(ZWPp;6xPzZpfF-57W^^g`p{)})h>jOe~fQI?- zh0siY9tqANCcM!+=2u z1tP5kQb{Kd422#51M8Tb9za(7`UDkK&`Z=KEP^JLi2a3@nP35xUAS_C%S{u@O(7L# zoT3E7<@&LEbYpjEoDkOBW%8}=1cyVwFtnlz*Z>U;7+3|qJ2>ckD$Eo#+|lK+qtm(4 zJYk0kXDmL8yJFB081-C8FY&9Q(p0zy5eW*xwo-v+wXlg$;j2)>aG9VtHw-RKEJlQ7 z1y&Xaoxr~VFGo-%)fFPM)TL56c87X&m1bnM#-l>+TZyW6k{g-?$?;-pxao`U#^j99 zMFJsX%(rN0i_!o%X#>N_2!exs;4K5MVQ6~QiJZg0muU>HI6D$ zdFE;yI0QQ318@ijl6&-r^yUyi$Xz)E5OR+k;kP>=`)@OQ6}v2 z9aCeB->**GFOS%AZcI+@4_^A<`*Cy7m^&ctecz-kza$ilzYp%E-qxv^aK7O*Lu-3f zY*9TgHEtuNaWW^f~>sv)W0=6@CX=ymz;FRk!2b zjm%Xflf!w7=@Cihr08x-nYQMN7aFMcyvXcdVrCbw9+xT^lF8vKphyb3(kPj!s5F>W z2eVs0x>!;>8=wwtxrtg^ay&qJo%L1X_rbXLTQQ#Dui`}Eu%(EP$aueCz7_Acj?1il zb|8IkHB5kIon)n5Y+&O3BY-_{p%V%4n|`$lB4aR2)WjHMIOc~ zU*YhF+drL0(1cni=B%?n+v_1$eWx^3_7X&MywL~`hJnpc=WDl}Dx@>fIaa0dhuKa@ z;d}NT0Oq;*Rca|`j2SXKh4DZGyrfSPy&T_xAA?Up-3nGQFt`dCU!kOhJ{<=j)0-RC zBjA6c8q5jIc>EWXMaE(=v}NyuEmkGWs4~}Dev5gDyc|5pVyy~f+4%7KYT=uO&lX4G zgP`seTBMp>pqY}dorIN3k5qZEVW!O1w zT)im;Expbv(=Qp)uNYG=>tNEecV4Ymy?E&6OS>;e|E0k5*Z)2?>0PJjw_M`pK+PVD zO4P`p^%V@MAV^PzdN$8T#jHL7&4^RbL!4R?BUca=l$h`#E#)p-hCR41z~CNtOU*&Y zK*VmS0U26;#LgZ%eaWC#K8Pr34BT-&@`yU}G*!xk)gV%=_9;}LH9Sw1fifqS&+Y{} z57xMZggQlvAH8c{#Crx<=JQ|;wp?Ary0uAr;hx*yJ=%Ud-l|9TEVsZdhM=uRY{3Km zU+4lp*ZObLz({ipav$q8f$Nk3YarOJa#^F8w4wR+ZPz|1zq<2u%hB`lrpxMUsyj88 zn>U`+|7L5u^z)A3^|#%?A?w<~A(L0DC$9Os^HWLb+Jo8O11tyPtlQ&sU z4k<8j4#5^-INT6J_H;!Y?24%|#~;)t9n{2>HhKNIYQ)>0d^c$hD(go_&vB1m6p*~k zUxLosO9!VeddkKj$XOkLL#T|48A6IsKZD^k#_`Ct9+tES>KRCa9W`T#`!D_wx?)S* z>fJMr-bz2OK!7Isnh7@jdY7bDoz!3mKd*?q+#S)>8B%NTJ+1OQs`jW+A(-n_(cxAK z8bR$3n~UHvD513j6`Nzdfb5Y1Jvao#YbK~hu~Kb^Tu5`gnT1}B0V|8h9U$cj6<0F#mXTJMXdRR zj6-O`XLCNLT&!Ek2tqiA(12Aj*f@m4jA-kyWFGjTJ#EA0tPmg19VX&Ek7C^WQ~0+M ze^&4B`Kb4ZKb?>1UM$@4AI+e@e}(vu?eQJHHit0Bi-<$4`er=0*}fHX2+qcD2Zzvg z0skID4)8n-{J zdS+>84OOP09(Kh#7$^uqVfeSvNXrA=@yb<1X*R(_CxWmT8qsGKN zx5K_T9rVY_!LNLXj;_zfqTxa&nmc<+mO-FwXv!kQTu9d)K|na-(8-AWAvTu?IYzAh z5UBVfmvxjh8?l>_5V1jala$U(=d@+uO#y-&~ACy}Td29V3E2gq}if2}^S&VO5rA!gE~3 zTR2AG4B`F|oN_oPxr45^8${UCg9mJWjECtDv0V|YpqOcTfa;mJ2S*6*^x#_p1E{QX zLcoN;IE2zyP|U(xhhuAXfY{t1h|)4SGBJnHtVRA1a)$6!d;vxH^hGY;QZ15akY3_k zqIE(GEwt|}(YUjAT6isaODg2yJ36NBQYF;r(#~|wsO?TiJJCz#=q7XIl}_)oZIfyh zQ_r={xTt{r^hE1(8){OP=Z3uc;h;DYMI0e{554~&g$?7om&dt$azBK1W@O%0A2o|**|!3){T=^pWT{Oln~^M<4>49NW4 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

DE#bD=}S+S?u|~gMJDP3W7ECD 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 { + (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) { + resolve(texture); + }) +}) From 04a2b631ccf8890c826a78021d836685f25f0b00 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Sat, 25 Feb 2017 20:52:25 -0500 Subject: [PATCH 09/14] readme --- README.md | 108 ++++-------------------------------------------------- 1 file changed, 7 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index 342e5a3..bce91b6 100644 --- a/README.md +++ b/README.md @@ -1,105 +1,11 @@ -# Project 6: Implicit surfaces - Marching cubes +Lava Lamp: FlowOn -**Goal:** Implement an isosurface created from metaballs using the marching cubes algorithm. +Marching Cubes: +Created a lava lamp with implicit surfaces. The "lava" is created by a collection of spheres. The isosurface is defined by the summation of the sphere influences. Sphere influence is 1 at the sphere boundary and decreases farther away from the sphere. The Isosurface region is all points where the total sphere influence is greater than a set isolevel value. These calculations are done on each vertex of a voxel grid. Once each vertex has a isovalue, the triangle mesh is defined according to the values at each of the 8 voxel corners. This configuation is stored in a 8 bit value, where each bit represents a vertex and whether it is "in" or "out" of the surface. The 8 bit values goes into a look up table that returns a 12 bit value containing the edges that are intersected by the mesh. The points that define the mesh are determined by interpolating between the isovalues on the corners. Finally, the faces are defined by a second table. This algorithm is called the marching cubes algorithm -Metaballs are organic-looking n-dimensional objects. We will be implementing a 3-dimensional metaballs. They are great to make bloppy shapes. An isosurface is created whenever the metaball function crosses a certain threshold, called isolevel. The metaball function describes the total influences of each metaball to a given points. A metaball influence is a function between its radius and distance to the point: +The metaball's position and velocity is update at every time step. The position is maintained within the boundary by calculating the distance to the boundaries and updating the velocity according to this value. -`f(point) = (radius * radius) / (distance * distance)` +Shaders: +The lava is shaded with GLSL matcap shader, using a lit sphere texture. The idea behind this shader uses environment mapping. The lava lamp has a emissive lambert shader (THREE.js). The color is smoothed with a procedural cosine color mapping. I modeled the lamp in Autodesk Maya. -By summing up all these influences, you effectively describes all the points that are greater than the isolevel as inside, and less than the isolevel as outside (or vice versa). As an observation, the bigger the metaball's radius is, the bigger its influence is. - -Marching cubes essentially voxelize the space, then generate triangles based on the density function distribution at the corners of each voxel. By increasing the voxelized grid's resolution, the surface eventually gets that blobby, organic look of the metaballs. Marching cubes can achieve a similar effect to ray marching for rendering implicit surfaces, but in addition to the rendered image, you also retain actual geometries. - -Marching cubes are commonly used in MRI scanning, where you can generate geometries for the scans. Marching cubes are also used to generate complex terrains with caves in games. The additional geometry information can handily support collision and other physical calculation for game engines. For example, their bounding boxes can then be computed to construct the acceleration data structure for collisions. - -**Warning**: this assignment option requires more effort than the ray marching option. The two base codes diverge significantly, so switching options midway can be costly for your time and effort. - -## Resources -We suggest reading the following resources before starting your assignment: - -- [Generating complex terrain](https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch01.html) from [GPU Gems 3](https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_pref01.html). -- [Polygonising a scalar field](http://paulbourke.net/geometry/polygonise/) by Paul Bourke. -- [Marching squares](http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/) by Jamie Wong. - -## Base code framework - -We have provided a basecode as a reference. You are welcome to modify the framework for your project. The basecode implements metaballs on the CPU. - -_main.js_: - - - `App`: - -This is a global configuration object. All information for the marching cubes are stored here. - -**Note**: `App.visualDebug` is a global control of all the visual debugging components. Even though it is helpful for development, it could be memory intensive. Toggle this flag off for better perforamance at high resolution. - -_marching_cubes.js_: - - - `class MarchingCubes`: - This class encapsulates everything about the metaballs, grid, voxels, and sampling information. - - - `class Voxel`: - This class contains information about a single voxel, and its sample points. Polygonization happens here. - -_inspect_point.js_: - - - `class InspectPoint`: - This class simply contains a single sample point that can output its value on the screen at its pixel location. - -_metaball.js_: - - - `class Metaball`: - This class represents a single metaball. - -_marching_cube_LUT.js_: - -This file contains the edge table and the triangle table for the marching cubes. - -## Animate metaballs (5 points) -Implement the `update` for metaballs to move its position based velocity. Reverse the velocity whenever the metaball goes out of bounds. Since the metaball function is not well defined at the boundaries, maintain an additional small margin so that the metaball can reverse its moving direction before reaching the bounds. - -## Metaball function (2 points) -Implement the metaball function inside `sample` of `MarchingCubes`. This function should return the total influences of all moving metaballs with respect to a given point. - -## Sampling at corners (15 points) -In order to polygonize a voxel, generate new samples at each corner of the voxel. Their isovalues must be updated as the metaball function changes due of metaballs moving. - -## Polygonization (50 points) -Implement `polygonize` inside `Cell` class. This function should return the list of **vertices** and **normals** of the triangles polygonized in the voxel. - -### Vertices (30 points out of 50) -To compute the vertices, we have provided the look-up tables from Paul Bourke's. The table assumes the following indexing scheme: -![](./ref_voxel_indexing.png) - -- _The eight corners can be represented as an 8-bit number, where 1 means the isovalue is above or below the isolevel based on your implementation._ -- _The twelve edges can be represented as a 12-bit number, where 1 means that the isosurface intersects with this edge._ - -- **EDGE_TABLE**: This table returns a 12-bit number that represents the edges intersected by the isosurface. For each intersected edge, compute the linearly interpolated vertex position on the edge according to the isovalue at each end corner of the edge. - -- **TRI_TABLE**: This table acts as the triangle indices. Every 16 elements in the table represents a possible polygonizing configuration. Within each configuration, every three consecutive elements represents the indices of a triangle that should be created from the edges above. - -### Normals (20 points out of 50) -Compute the normals using the gradient of the vertex with respect to the x, y, and z. The normals are then used for shading different materials. - -## Meshing (18 points) -The mesh for the metaball's isosurface should be created once. At each frame, using the list of **vertices** and **normals** polygonized from the voxels, update the mesh's geometry for the isosurface. Notice that the total volume of the mesh does change. - -## Materials and post-processing (10 points) -Interesting shader materials beyond just the provided threejs materials. We encourage using your previous shaders assignment for this part. - -## Extra credits (Up to 30 points) -- Metaball can be positive or negative. A negative metaball will substract from the surface, which pushed the surface inward. **Implement a scene with both positive and negative metaballs. (10 points)** -- **More implicit surfaces!** For example: planes, mesh, etc.). Some very interesting ideas are to blend your metaballs into those surfaces. **(5 points for each)** - -## Submission - -- Update `README.md` to contain a solid description of your project -- Publish your project to gh-pages. `npm run deploy`. It should now be visible at http://username.github.io/repo-name -- Create a [pull request](https://help.github.com/articles/creating-a-pull-request/) to this repository, and in the comment, include a link to your published project. -- Submit the link to your pull request on Canvas. - -## Deploy -- `npm run build` -- Add and commit all changes -- `npm run deploy` -- If you're having problems with assets not linking correctly, make sure you wrap you're filepaths in `require()`. This will make the bundler package and your static assets as well. So, instead of `loadTexture('./images/thing.bmp')`, do `loadTexture(require('./images/thing.bmp'))`. \ No newline at end of file +Since watching the lava lamp and metaballs move is so soothing, I decided to create a website with inspiration quotes (A new one each time the web page loads). \ No newline at end of file From 6332b5857026155e34f62a028baf81c5566dba20 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Mon, 27 Feb 2017 20:19:27 -0500 Subject: [PATCH 10/14] README --- README.md | 11 +- glass.obj | 4423 --------------------------------------------------- lamp.obj | 1211 -------------- src/main.js | 6 +- 4 files changed, 6 insertions(+), 5645 deletions(-) delete mode 100644 glass.obj delete mode 100644 lamp.obj diff --git a/README.md b/README.md index bce91b6..bd29874 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,6 @@ -Lava Lamp: FlowOn - -Marching Cubes: -Created a lava lamp with implicit surfaces. The "lava" is created by a collection of spheres. The isosurface is defined by the summation of the sphere influences. Sphere influence is 1 at the sphere boundary and decreases farther away from the sphere. The Isosurface region is all points where the total sphere influence is greater than a set isolevel value. These calculations are done on each vertex of a voxel grid. Once each vertex has a isovalue, the triangle mesh is defined according to the values at each of the 8 voxel corners. This configuation is stored in a 8 bit value, where each bit represents a vertex and whether it is "in" or "out" of the surface. The 8 bit values goes into a look up table that returns a 12 bit value containing the edges that are intersected by the mesh. The points that define the mesh are determined by interpolating between the isovalues on the corners. Finally, the faces are defined by a second table. This algorithm is called the marching cubes algorithm - -The metaball's position and velocity is update at every time step. The position is maintained within the boundary by calculating the distance to the boundaries and updating the velocity according to this value. +Lava Lamp Shaders: -The lava is shaded with GLSL matcap shader, using a lit sphere texture. The idea behind this shader uses environment mapping. The lava lamp has a emissive lambert shader (THREE.js). The color is smoothed with a procedural cosine color mapping. I modeled the lamp in Autodesk Maya. +The lava is shaded with GLSL matcap shader, using a lit sphere texture. The color is smoothed with a cosine color mapping. I modeled the lamp in Maya. -Since watching the lava lamp and metaballs move is so soothing, I decided to create a website with inspiration quotes (A new one each time the web page loads). \ No newline at end of file +Since watching the lava lamp / metaballs and changing colors are so soothing, I decided to create a website with inspiration quotes (A new one each time the web page loads). \ No newline at end of file diff --git a/glass.obj b/glass.obj deleted file mode 100644 index 11a96f9..0000000 --- a/glass.obj +++ /dev/null @@ -1,4423 +0,0 @@ -# This file uses centimeters as units for non-parametric coordinates. - -mtllib glass.mtl -g default -v 1.034828 0.023645 5.000000 -v 2.478410 15.929955 5.000000 -v 7.521590 15.929955 5.000000 -v 8.965172 0.023645 5.000000 -v 1.417236 7.928881 5.000000 -v 8.582764 7.928881 5.000000 -v 3.208639 7.928881 1.897309 -v 3.017437 0.023645 1.566141 -v 0.875664 2.621381 5.000000 -v 2.937856 2.621381 1.428304 -v 1.428295 2.621381 2.937872 -v 1.566132 0.023645 3.017453 -v 0.821208 0.615620 5.000000 -v 1.381136 0.615620 2.910645 -v 0.963631 0.615620 3.918452 -v 1.169970 0.023645 3.973740 -v 0.894509 0.142910 5.000000 -v 1.034433 0.142910 3.937423 -v 0.929731 0.142910 4.464145 -v 1.068846 0.023645 4.482460 -v 0.956291 0.039097 5.000000 -v 0.990983 0.039097 4.472209 -v 0.964993 0.039097 4.735543 -v 1.043362 0.023645 4.740679 -v 0.993465 0.020326 5.000000 -v 1.002088 0.020326 4.737974 -v 1.027838 0.020326 4.477061 -v 1.094110 0.039097 3.953414 -v 1.111107 0.023645 4.226447 -v 1.034081 0.039097 4.211125 -v 1.070540 0.020326 4.218377 -v 1.130017 0.020326 3.963035 -v 1.444614 0.142910 2.947294 -v 1.336707 0.023645 3.482630 -v 1.207070 0.142910 3.428933 -v 1.264149 0.039097 3.452576 -v 1.245260 0.023645 3.725444 -v 1.170891 0.039097 3.700200 -v 1.206092 0.020326 3.712149 -v 1.298493 0.020326 3.466802 -v 1.498118 0.039097 2.978185 -v 1.443833 0.023645 3.246301 -v 1.373397 0.039097 3.211566 -v 1.406737 0.020326 3.228007 -v 1.530311 0.020326 2.996772 -v 2.910628 0.615620 1.381145 -v 2.196266 0.023645 2.196279 -v 2.045218 0.615620 2.045232 -v 2.097048 0.142910 2.097061 -v 1.854217 0.023645 2.586172 -v 1.742894 0.142910 2.500752 -v 1.791910 0.039097 2.538362 -v 1.703097 0.023645 2.797079 -v 1.637796 0.039097 2.753446 -v 1.668705 0.020326 2.774099 -v 1.821402 0.020326 2.560992 -v 2.140734 0.039097 2.140747 -v 2.018867 0.023645 2.385640 -v 1.959821 0.039097 2.333858 -v 1.987769 0.020326 2.358368 -v 2.167019 0.020326 2.167032 -v 2.947278 0.142910 1.444624 -v 2.586158 0.023645 1.854228 -v 2.500737 0.142910 1.742906 -v 2.538347 0.039097 1.791921 -v 2.385627 0.023645 2.018879 -v 2.333844 0.039097 1.959833 -v 2.358355 0.020326 1.987781 -v 2.560978 0.020326 1.821413 -v 2.978169 0.039097 1.498128 -v 2.797064 0.023645 1.703107 -v 2.753431 0.039097 1.637806 -v 2.774084 0.020326 1.668715 -v 2.996756 0.020326 1.530321 -v 1.117453 5.293516 5.000000 -v 3.058749 5.293516 1.637695 -v 1.637686 5.293516 3.058764 -v 0.974417 3.840676 5.000000 -v 1.513815 3.840676 2.987248 -v 2.987231 3.840676 1.513825 -v 1.897300 7.928881 3.208653 -v 1.254732 6.544681 5.000000 -v 1.756570 6.544681 3.127403 -v 3.127388 6.544681 1.756579 -v 9.124336 2.621381 5.000000 -v 6.982563 0.023645 1.566141 -v 7.062144 2.621381 1.428304 -v 5.000000 0.023645 1.034828 -v 5.000000 2.621381 0.875664 -v 5.000000 0.615620 0.821208 -v 3.973732 0.023645 1.169972 -v 3.918442 0.615620 0.963634 -v 3.937414 0.142910 1.034436 -v 3.482617 0.023645 1.336712 -v 3.428920 0.142910 1.207076 -v 3.452563 0.039097 1.264154 -v 3.246287 0.023645 1.443840 -v 3.211552 0.039097 1.373404 -v 3.227993 0.020326 1.406744 -v 3.466789 0.020326 1.298498 -v 3.953405 0.039097 1.094112 -v 3.725433 0.023645 1.245263 -v 3.700189 0.039097 1.170894 -v 3.712138 0.020326 1.206095 -v 3.963026 0.020326 1.130019 -v 5.000000 0.142910 0.894509 -v 4.482456 0.023645 1.068847 -v 4.464141 0.142910 0.929731 -v 4.472205 0.039097 0.990984 -v 4.226440 0.023645 1.111109 -v 4.211118 0.039097 1.034083 -v 4.218370 0.020326 1.070542 -v 4.477057 0.020326 1.027839 -v 5.000000 0.039097 0.956291 -v 4.740677 0.023645 1.043362 -v 4.735540 0.039097 0.964994 -v 4.737971 0.020326 1.002088 -v 5.000000 0.020326 0.993465 -v 7.089372 0.615620 1.381145 -v 6.026268 0.023645 1.169972 -v 6.081558 0.615620 0.963634 -v 6.062586 0.142910 1.034436 -v 5.517544 0.023645 1.068847 -v 5.535859 0.142910 0.929731 -v 5.527795 0.039097 0.990984 -v 5.259323 0.023645 1.043362 -v 5.264460 0.039097 0.964994 -v 5.262029 0.020326 1.002088 -v 5.522943 0.020326 1.027839 -v 6.046595 0.039097 1.094112 -v 5.773560 0.023645 1.111109 -v 5.788882 0.039097 1.034083 -v 5.781630 0.020326 1.070542 -v 6.036974 0.020326 1.130019 -v 7.052722 0.142910 1.444624 -v 6.517383 0.023645 1.336712 -v 6.571080 0.142910 1.207076 -v 6.547437 0.039097 1.264154 -v 6.274567 0.023645 1.245263 -v 6.299811 0.039097 1.170894 -v 6.287862 0.020326 1.206095 -v 6.533211 0.020326 1.298498 -v 7.021831 0.039097 1.498128 -v 6.753713 0.023645 1.443840 -v 6.788448 0.039097 1.373404 -v 6.772007 0.020326 1.406744 -v 7.003244 0.020326 1.530321 -v 8.433868 0.023645 3.017453 -v 8.571705 2.621381 2.937872 -v 8.618864 0.615620 2.910645 -v 7.803734 0.023645 2.196279 -v 7.954782 0.615620 2.045232 -v 7.902952 0.142910 2.097061 -v 7.413842 0.023645 1.854228 -v 7.499263 0.142910 1.742906 -v 7.461653 0.039097 1.791921 -v 7.202936 0.023645 1.703107 -v 7.246569 0.039097 1.637806 -v 7.225916 0.020326 1.668715 -v 7.439022 0.020326 1.821413 -v 7.859266 0.039097 2.140747 -v 7.614373 0.023645 2.018879 -v 7.666156 0.039097 1.959833 -v 7.641645 0.020326 1.987781 -v 7.832981 0.020326 2.167032 -v 8.555386 0.142910 2.947294 -v 8.145783 0.023645 2.586172 -v 8.257106 0.142910 2.500752 -v 8.208090 0.039097 2.538362 -v 7.981133 0.023645 2.385640 -v 8.040179 0.039097 2.333858 -v 8.012231 0.020326 2.358368 -v 8.178598 0.020326 2.560992 -v 8.501882 0.039097 2.978185 -v 8.296903 0.023645 2.797079 -v 8.362204 0.039097 2.753446 -v 8.331295 0.020326 2.774099 -v 8.469689 0.020326 2.996772 -v 9.178792 0.615620 5.000000 -v 8.830030 0.023645 3.973740 -v 9.036369 0.615620 3.918452 -v 8.965567 0.142910 3.937423 -v 8.663293 0.023645 3.482630 -v 8.792930 0.142910 3.428933 -v 8.735851 0.039097 3.452576 -v 8.556167 0.023645 3.246301 -v 8.626603 0.039097 3.211566 -v 8.593263 0.020326 3.228007 -v 8.701507 0.020326 3.466802 -v 8.905890 0.039097 3.953414 -v 8.754740 0.023645 3.725444 -v 8.829109 0.039097 3.700200 -v 8.793908 0.020326 3.712149 -v 8.869983 0.020326 3.963035 -v 9.105491 0.142910 5.000000 -v 8.931154 0.023645 4.482460 -v 9.070269 0.142910 4.464145 -v 9.009017 0.039097 4.472209 -v 8.888893 0.023645 4.226447 -v 8.965919 0.039097 4.211125 -v 8.929460 0.020326 4.218377 -v 8.972162 0.020326 4.477061 -v 9.043709 0.039097 5.000000 -v 8.956638 0.023645 4.740679 -v 9.035007 0.039097 4.735543 -v 8.997912 0.020326 4.737974 -v 9.006535 0.020326 5.000000 -v 6.791361 7.928881 1.897309 -v 6.941251 5.293516 1.637695 -v 5.000000 5.293516 1.117453 -v 5.000000 3.840676 0.974417 -v 7.012769 3.840676 1.513825 -v 5.000000 7.928881 1.417236 -v 5.000000 6.544681 1.254732 -v 6.872612 6.544681 1.756579 -v 8.882547 5.293516 5.000000 -v 8.362314 5.293516 3.058764 -v 8.486185 3.840676 2.987248 -v 9.025583 3.840676 5.000000 -v 8.102700 7.928881 3.208653 -v 8.243430 6.544681 3.127403 -v 8.745268 6.544681 5.000000 -v 3.739220 15.929955 2.816291 -v 1.753123 10.600694 5.000000 -v 3.376580 10.600694 2.188188 -v 2.188181 10.600694 3.376593 -v 1.575982 9.216277 5.000000 -v 2.034775 9.216277 3.288024 -v 3.288010 9.216277 2.034783 -v 2.109344 13.271226 5.000000 -v 3.554689 13.271226 2.496678 -v 2.496671 13.271226 3.554700 -v 1.924119 11.898438 5.000000 -v 2.336265 11.898438 3.462090 -v 3.462077 11.898438 2.336272 -v 2.816285 15.929955 3.739230 -v 2.288120 14.570229 5.000000 -v 2.651492 14.570229 3.644087 -v 3.644076 14.570229 2.651499 -v 8.246877 10.600694 5.000000 -v 6.623420 10.600694 2.188188 -v 5.000000 10.600694 1.753123 -v 5.000000 9.216277 1.575982 -v 6.711990 9.216277 2.034783 -v 7.811819 10.600694 3.376593 -v 7.965225 9.216277 3.288024 -v 8.424018 9.216277 5.000000 -v 6.260780 15.929955 2.816291 -v 6.445311 13.271226 2.496678 -v 5.000000 13.271226 2.109344 -v 5.000000 11.898438 1.924119 -v 6.537923 11.898438 2.336272 -v 5.000000 15.929955 2.478410 -v 5.000000 14.570229 2.288120 -v 6.355924 14.570229 2.651499 -v 7.890656 13.271226 5.000000 -v 7.503329 13.271226 3.554700 -v 7.663735 11.898438 3.462090 -v 8.075881 11.898438 5.000000 -v 7.183715 15.929955 3.739230 -v 7.348508 14.570229 3.644087 -v 7.711880 14.570229 5.000000 -v 6.982563 0.023645 8.433859 -v 6.791361 7.928881 8.102691 -v 7.062144 2.621381 8.571696 -v 8.433868 0.023645 6.982547 -v 8.571705 2.621381 7.062128 -v 8.618864 0.615620 7.089355 -v 8.830030 0.023645 6.026260 -v 9.036369 0.615620 6.081548 -v 8.965567 0.142910 6.062577 -v 8.931154 0.023645 5.517540 -v 9.070269 0.142910 5.535855 -v 9.009017 0.039097 5.527791 -v 8.956638 0.023645 5.259321 -v 9.035007 0.039097 5.264457 -v 8.997912 0.020326 5.262026 -v 8.972162 0.020326 5.522939 -v 8.905890 0.039097 6.046586 -v 8.888893 0.023645 5.773553 -v 8.965919 0.039097 5.788875 -v 8.929460 0.020326 5.781623 -v 8.869983 0.020326 6.036965 -v 8.555386 0.142910 7.052706 -v 8.663293 0.023645 6.517370 -v 8.792930 0.142910 6.571067 -v 8.735851 0.039097 6.547424 -v 8.754740 0.023645 6.274556 -v 8.829109 0.039097 6.299800 -v 8.793908 0.020326 6.287851 -v 8.701507 0.020326 6.533198 -v 8.501882 0.039097 7.021815 -v 8.556167 0.023645 6.753699 -v 8.626603 0.039097 6.788434 -v 8.593263 0.020326 6.771993 -v 8.469689 0.020326 7.003228 -v 7.089372 0.615620 8.618855 -v 7.803734 0.023645 7.803721 -v 7.954782 0.615620 7.954768 -v 7.902952 0.142910 7.902939 -v 8.145783 0.023645 7.413828 -v 8.257106 0.142910 7.499248 -v 8.208090 0.039097 7.461638 -v 8.296903 0.023645 7.202921 -v 8.362204 0.039097 7.246554 -v 8.331295 0.020326 7.225901 -v 8.178598 0.020326 7.439008 -v 7.859266 0.039097 7.859253 -v 7.981133 0.023645 7.614360 -v 8.040179 0.039097 7.666142 -v 8.012231 0.020326 7.641632 -v 7.832981 0.020326 7.832968 -v 7.052722 0.142910 8.555376 -v 7.413842 0.023645 8.145772 -v 7.499263 0.142910 8.257094 -v 7.461653 0.039097 8.208079 -v 7.614373 0.023645 7.981121 -v 7.666156 0.039097 8.040167 -v 7.641645 0.020326 8.012219 -v 7.439022 0.020326 8.178587 -v 7.021831 0.039097 8.501872 -v 7.202936 0.023645 8.296893 -v 7.246569 0.039097 8.362194 -v 7.225916 0.020326 8.331285 -v 7.003244 0.020326 8.469679 -v 6.941251 5.293516 8.362305 -v 8.362314 5.293516 6.941236 -v 8.486185 3.840676 7.012752 -v 7.012769 3.840676 8.486175 -v 8.102700 7.928881 6.791347 -v 8.243430 6.544681 6.872597 -v 6.872612 6.544681 8.243421 -v 3.017437 0.023645 8.433859 -v 2.937856 2.621381 8.571696 -v 5.000000 0.023645 8.965172 -v 5.000000 2.621381 9.124336 -v 5.000000 0.615620 9.178792 -v 6.026268 0.023645 8.830028 -v 6.081558 0.615620 9.036366 -v 6.062586 0.142910 8.965564 -v 6.517383 0.023645 8.663288 -v 6.571080 0.142910 8.792924 -v 6.547437 0.039097 8.735846 -v 6.753713 0.023645 8.556160 -v 6.788448 0.039097 8.626596 -v 6.772007 0.020326 8.593256 -v 6.533211 0.020326 8.701502 -v 6.046595 0.039097 8.905888 -v 6.274567 0.023645 8.754737 -v 6.299811 0.039097 8.829106 -v 6.287862 0.020326 8.793905 -v 6.036974 0.020326 8.869981 -v 5.000000 0.142910 9.105491 -v 5.517544 0.023645 8.931153 -v 5.535859 0.142910 9.070269 -v 5.527795 0.039097 9.009016 -v 5.773560 0.023645 8.888891 -v 5.788882 0.039097 8.965917 -v 5.781630 0.020326 8.929458 -v 5.522943 0.020326 8.972161 -v 5.000000 0.039097 9.043709 -v 5.259323 0.023645 8.956638 -v 5.264460 0.039097 9.035006 -v 5.262029 0.020326 8.997912 -v 5.000000 0.020326 9.006535 -v 2.910628 0.615620 8.618855 -v 3.973732 0.023645 8.830028 -v 3.918442 0.615620 9.036366 -v 3.937414 0.142910 8.965564 -v 4.482456 0.023645 8.931153 -v 4.464141 0.142910 9.070269 -v 4.472205 0.039097 9.009016 -v 4.740677 0.023645 8.956638 -v 4.735540 0.039097 9.035006 -v 4.737971 0.020326 8.997912 -v 4.477057 0.020326 8.972161 -v 3.953405 0.039097 8.905888 -v 4.226440 0.023645 8.888891 -v 4.211118 0.039097 8.965917 -v 4.218370 0.020326 8.929458 -v 3.963026 0.020326 8.869981 -v 2.947278 0.142910 8.555376 -v 3.482617 0.023645 8.663288 -v 3.428920 0.142910 8.792924 -v 3.452563 0.039097 8.735846 -v 3.725433 0.023645 8.754737 -v 3.700189 0.039097 8.829106 -v 3.712138 0.020326 8.793905 -v 3.466789 0.020326 8.701502 -v 2.978169 0.039097 8.501872 -v 3.246287 0.023645 8.556160 -v 3.211552 0.039097 8.626596 -v 3.227993 0.020326 8.593256 -v 2.996756 0.020326 8.469679 -v 1.566132 0.023645 6.982547 -v 1.428295 2.621381 7.062128 -v 1.381136 0.615620 7.089355 -v 2.196266 0.023645 7.803721 -v 2.045218 0.615620 7.954768 -v 2.097048 0.142910 7.902939 -v 2.586158 0.023645 8.145772 -v 2.500737 0.142910 8.257094 -v 2.538347 0.039097 8.208079 -v 2.797064 0.023645 8.296893 -v 2.753431 0.039097 8.362194 -v 2.774084 0.020326 8.331285 -v 2.560978 0.020326 8.178587 -v 2.140734 0.039097 7.859253 -v 2.385627 0.023645 7.981121 -v 2.333844 0.039097 8.040167 -v 2.358355 0.020326 8.012219 -v 2.167019 0.020326 7.832968 -v 1.444614 0.142910 7.052706 -v 1.854217 0.023645 7.413828 -v 1.742894 0.142910 7.499248 -v 1.791910 0.039097 7.461638 -v 2.018867 0.023645 7.614360 -v 1.959821 0.039097 7.666142 -v 1.987769 0.020326 7.641632 -v 1.821402 0.020326 7.439008 -v 1.498118 0.039097 7.021815 -v 1.703097 0.023645 7.202921 -v 1.637796 0.039097 7.246554 -v 1.668705 0.020326 7.225901 -v 1.530311 0.020326 7.003228 -v 1.169970 0.023645 6.026260 -v 0.963631 0.615620 6.081548 -v 1.034433 0.142910 6.062577 -v 1.336707 0.023645 6.517370 -v 1.207070 0.142910 6.571067 -v 1.264149 0.039097 6.547424 -v 1.443833 0.023645 6.753699 -v 1.373397 0.039097 6.788434 -v 1.406737 0.020326 6.771993 -v 1.298493 0.020326 6.533198 -v 1.094110 0.039097 6.046586 -v 1.245260 0.023645 6.274556 -v 1.170891 0.039097 6.299800 -v 1.206092 0.020326 6.287851 -v 1.130017 0.020326 6.036965 -v 3.208639 7.928881 8.102691 -v 3.058749 5.293516 8.362305 -v 5.000000 5.293516 8.882547 -v 5.000000 3.840676 9.025583 -v 2.987231 3.840676 8.486175 -v 5.000000 7.928881 8.582764 -v 5.000000 6.544681 8.745268 -v 3.127388 6.544681 8.243421 -v 1.637686 5.293516 6.941236 -v 1.513815 3.840676 7.012752 -v 1.897300 7.928881 6.791347 -v 1.756570 6.544681 6.872597 -v 6.260780 15.929955 7.183709 -v 6.623420 10.600694 7.811812 -v 7.811819 10.600694 6.623407 -v 7.965225 9.216277 6.711976 -v 6.711990 9.216277 7.965217 -v 6.445311 13.271226 7.503322 -v 7.503329 13.271226 6.445300 -v 7.663735 11.898438 6.537910 -v 6.537923 11.898438 7.663728 -v 7.183715 15.929955 6.260770 -v 7.348508 14.570229 6.355913 -v 6.355924 14.570229 7.348501 -v 3.376580 10.600694 7.811812 -v 5.000000 10.600694 8.246877 -v 5.000000 9.216277 8.424018 -v 3.288010 9.216277 7.965217 -v 2.188181 10.600694 6.623407 -v 2.034775 9.216277 6.711976 -v 3.739220 15.929955 7.183709 -v 3.554689 13.271226 7.503322 -v 5.000000 13.271226 7.890656 -v 5.000000 11.898438 8.075881 -v 3.462077 11.898438 7.663728 -v 5.000000 15.929955 7.521590 -v 5.000000 14.570229 7.711880 -v 3.644076 14.570229 7.348501 -v 2.496671 13.271226 6.445300 -v 2.336265 11.898438 6.537910 -v 2.816285 15.929955 6.260770 -v 2.651492 14.570229 6.355913 -vt 1.000000 0.916667 -vt 1.000000 1.000000 -vt 0.957053 0.916667 -vt 1.000000 0.416667 -vt 1.000000 0.500000 -vt 0.957053 0.416667 -vt 0.710046 0.416667 -vt 0.710046 0.500000 -vt 0.646478 0.416667 -vt 0.710046 0.083333 -vt 0.710046 0.166666 -vt 0.646478 0.083333 -vt 0.414458 0.083333 -vt 0.414458 0.166666 -vt 0.207229 0.166666 -vt 0.207229 0.000000 -vt 0.414458 0.000000 -vt 0.207229 0.083333 -vt 0.103615 0.083333 -vt 0.103615 0.062500 -vt 0.207229 0.041667 -vt 0.103615 0.041667 -vt 0.103615 0.020833 -vt 0.051807 0.041667 -vt 0.051807 0.031250 -vt 0.051807 0.020833 -vt 0.051807 0.010417 -vt 0.025904 0.010417 -vt 0.025904 0.000000 -vt 0.051807 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.010417 -vt 0.025904 0.020833 -vt 0.025904 0.031250 -vt 0.000000 0.020833 -vt 0.000000 0.031250 -vt 0.025904 0.041667 -vt 0.051807 0.083333 -vt 0.051807 0.072916 -vt 0.051807 0.062500 -vt 0.051807 0.052083 -vt 0.025904 0.052083 -vt 0.000000 0.041667 -vt 0.000000 0.052083 -vt 0.025904 0.062500 -vt 0.025904 0.072916 -vt 0.000000 0.062500 -vt 0.000000 0.072916 -vt 0.025904 0.083333 -vt 0.103615 0.145833 -vt 0.103615 0.125000 -vt 0.207229 0.125000 -vt 0.103615 0.104166 -vt 0.051807 0.125000 -vt 0.051807 0.114583 -vt 0.051807 0.104166 -vt 0.051807 0.093750 -vt 0.025904 0.093750 -vt 0.000000 0.083333 -vt 0.000000 0.093750 -vt 0.025904 0.104166 -vt 0.025904 0.114583 -vt 0.000000 0.104166 -vt 0.000000 0.114583 -vt 0.025904 0.125000 -vt 0.103615 0.166666 -vt 0.051807 0.166666 -vt 0.051807 0.156250 -vt 0.051807 0.145833 -vt 0.051807 0.135416 -vt 0.025904 0.135416 -vt 0.000000 0.125000 -vt 0.000000 0.135416 -vt 0.025904 0.145833 -vt 0.025904 0.156250 -vt 0.000000 0.145833 -vt 0.000000 0.156250 -vt 0.025904 0.166666 -vt 0.582909 0.083333 -vt 0.582909 0.166666 -vt 0.498684 0.083333 -vt 0.498684 0.000000 -vt 0.582909 0.000000 -vt 0.498684 0.166666 -vt 0.646478 0.000000 -vt 0.710046 0.000000 -vt 0.646478 0.166666 -vt 0.207229 0.458333 -vt 0.207229 0.416667 -vt 0.414458 0.416667 -vt 0.207229 0.250000 -vt 0.414458 0.250000 -vt 0.414458 0.333334 -vt 0.103615 0.250000 -vt 0.103615 0.229167 -vt 0.207229 0.208333 -vt 0.103615 0.208333 -vt 0.103615 0.187500 -vt 0.051807 0.208333 -vt 0.051807 0.197916 -vt 0.051807 0.187500 -vt 0.051807 0.177083 -vt 0.025904 0.177083 -vt 0.000000 0.166666 -vt 0.000000 0.177083 -vt 0.025904 0.187500 -vt 0.025904 0.197916 -vt 0.000000 0.187500 -vt 0.000000 0.197916 -vt 0.025904 0.208333 -vt 0.051807 0.250000 -vt 0.051807 0.239583 -vt 0.051807 0.229167 -vt 0.051807 0.218750 -vt 0.025904 0.218750 -vt 0.000000 0.208333 -vt 0.000000 0.218750 -vt 0.025904 0.229167 -vt 0.025904 0.239583 -vt 0.000000 0.229167 -vt 0.000000 0.239583 -vt 0.025904 0.250000 -vt 0.207229 0.333334 -vt 0.103615 0.333334 -vt 0.103615 0.312500 -vt 0.207229 0.291667 -vt 0.103615 0.291667 -vt 0.103615 0.270833 -vt 0.051807 0.291667 -vt 0.051807 0.281250 -vt 0.051807 0.270833 -vt 0.051807 0.260417 -vt 0.025904 0.260417 -vt 0.000000 0.250000 -vt 0.000000 0.260417 -vt 0.025904 0.270833 -vt 0.025904 0.281250 -vt 0.000000 0.270833 -vt 0.000000 0.281250 -vt 0.025904 0.291667 -vt 0.051807 0.333334 -vt 0.051807 0.322917 -vt 0.051807 0.312500 -vt 0.051807 0.302084 -vt 0.025904 0.302084 -vt 0.000000 0.291667 -vt 0.000000 0.302084 -vt 0.025904 0.312500 -vt 0.025904 0.322917 -vt 0.000000 0.312500 -vt 0.000000 0.322917 -vt 0.025904 0.333334 -vt 0.103615 0.416667 -vt 0.103615 0.395834 -vt 0.207229 0.375000 -vt 0.103615 0.375000 -vt 0.103615 0.354167 -vt 0.051807 0.375000 -vt 0.051807 0.364584 -vt 0.051807 0.354167 -vt 0.051807 0.343750 -vt 0.025904 0.343750 -vt 0.000000 0.333334 -vt 0.000000 0.343750 -vt 0.025904 0.354167 -vt 0.025904 0.364584 -vt 0.000000 0.354167 -vt 0.000000 0.364584 -vt 0.025904 0.375000 -vt 0.051807 0.416667 -vt 0.051807 0.406250 -vt 0.051807 0.395834 -vt 0.051807 0.385417 -vt 0.025904 0.385417 -vt 0.000000 0.375000 -vt 0.000000 0.385417 -vt 0.025904 0.395834 -vt 0.025904 0.406250 -vt 0.000000 0.395834 -vt 0.000000 0.406250 -vt 0.025904 0.416667 -vt 0.103615 0.479167 -vt 0.103615 0.458333 -vt 0.103615 0.437500 -vt 0.051807 0.458333 -vt 0.051807 0.447917 -vt 0.051807 0.437500 -vt 0.051807 0.427084 -vt 0.025904 0.427084 -vt 0.000000 0.416667 -vt 0.000000 0.427084 -vt 0.025904 0.437500 -vt 0.025904 0.447917 -vt 0.000000 0.437500 -vt 0.000000 0.447917 -vt 0.025904 0.458333 -vt 0.051807 0.489583 -vt 0.051807 0.479167 -vt 0.051807 0.468750 -vt 0.025904 0.468750 -vt 0.000000 0.458333 -vt 0.000000 0.468750 -vt 0.025904 0.479167 -vt 0.025904 0.489583 -vt 0.051807 0.500000 -vt 0.000000 0.479167 -vt 0.000000 0.489583 -vt 0.025904 0.500000 -vt 0.710046 0.250000 -vt 0.710046 0.333334 -vt 0.646478 0.250000 -vt 0.498684 0.250000 -vt 0.582909 0.250000 -vt 0.582909 0.333334 -vt 0.498684 0.333334 -vt 0.646478 0.333334 -vt 0.498684 0.416667 -vt 0.582909 0.416667 -vt 0.582909 0.500000 -vt 0.498684 0.500000 -vt 0.646478 0.500000 -vt 1.000000 0.083333 -vt 1.000000 0.166666 -vt 0.957053 0.083333 -vt 0.818618 0.083333 -vt 0.818618 0.166666 -vt 0.764332 0.083333 -vt 0.764332 0.000000 -vt 0.818618 0.000000 -vt 0.764332 0.166666 -vt 0.914105 0.083333 -vt 0.914105 0.166666 -vt 0.866362 0.083333 -vt 0.866362 0.000000 -vt 0.914105 0.000000 -vt 0.866362 0.166666 -vt 0.957053 0.000000 -vt 1.000000 0.000000 -vt 0.957053 0.166666 -vt 0.764332 0.416667 -vt 0.818618 0.416667 -vt 0.818618 0.500000 -vt 0.764332 0.250000 -vt 0.818618 0.250000 -vt 0.818618 0.333334 -vt 0.764332 0.333334 -vt 0.764332 0.500000 -vt 1.000000 0.250000 -vt 1.000000 0.333334 -vt 0.957053 0.250000 -vt 0.866362 0.250000 -vt 0.914105 0.250000 -vt 0.914105 0.333334 -vt 0.866362 0.333334 -vt 0.957053 0.333334 -vt 0.866362 0.416667 -vt 0.914105 0.416667 -vt 0.914105 0.500000 -vt 0.866362 0.500000 -vt 0.957053 0.500000 -vt 0.646478 0.916667 -vt 0.710046 0.916667 -vt 0.710046 1.000000 -vt 0.710046 0.583333 -vt 0.710046 0.666666 -vt 0.646478 0.583333 -vt 0.414458 0.583333 -vt 0.414458 0.666666 -vt 0.207229 0.666666 -vt 0.207229 0.500000 -vt 0.414458 0.500000 -vt 0.207229 0.583333 -vt 0.103615 0.583333 -vt 0.103615 0.562500 -vt 0.207229 0.541667 -vt 0.103615 0.541667 -vt 0.103615 0.520833 -vt 0.051807 0.541667 -vt 0.051807 0.531250 -vt 0.051807 0.520833 -vt 0.051807 0.510417 -vt 0.025904 0.510417 -vt 0.000000 0.500000 -vt 0.000000 0.510417 -vt 0.025904 0.520833 -vt 0.025904 0.531250 -vt 0.000000 0.520833 -vt 0.000000 0.531250 -vt 0.025904 0.541667 -vt 0.051807 0.583333 -vt 0.051807 0.572916 -vt 0.051807 0.562500 -vt 0.051807 0.552083 -vt 0.025904 0.552083 -vt 0.000000 0.541667 -vt 0.000000 0.552083 -vt 0.025904 0.562500 -vt 0.025904 0.572916 -vt 0.000000 0.562500 -vt 0.000000 0.572916 -vt 0.025904 0.583333 -vt 0.103615 0.666666 -vt 0.103615 0.645833 -vt 0.207229 0.625000 -vt 0.103615 0.625000 -vt 0.103615 0.604166 -vt 0.051807 0.625000 -vt 0.051807 0.614583 -vt 0.051807 0.604166 -vt 0.051807 0.593750 -vt 0.025904 0.593750 -vt 0.000000 0.583333 -vt 0.000000 0.593750 -vt 0.025904 0.604166 -vt 0.025904 0.614583 -vt 0.000000 0.604166 -vt 0.000000 0.614583 -vt 0.025904 0.625000 -vt 0.051807 0.666666 -vt 0.051807 0.656250 -vt 0.051807 0.645833 -vt 0.051807 0.635416 -vt 0.025904 0.635416 -vt 0.000000 0.625000 -vt 0.000000 0.635416 -vt 0.025904 0.645833 -vt 0.025904 0.656250 -vt 0.000000 0.645833 -vt 0.000000 0.656250 -vt 0.025904 0.666666 -vt 0.582909 0.583333 -vt 0.582909 0.666666 -vt 0.498684 0.583333 -vt 0.498684 0.666666 -vt 0.646478 0.666666 -vt 0.207229 0.958333 -vt 0.207229 0.916667 -vt 0.414458 0.916667 -vt 0.207229 0.750000 -vt 0.414458 0.750000 -vt 0.414458 0.833334 -vt 0.103615 0.750000 -vt 0.103615 0.729167 -vt 0.207229 0.708333 -vt 0.103615 0.708333 -vt 0.103615 0.687500 -vt 0.051807 0.708333 -vt 0.051807 0.697916 -vt 0.051807 0.687500 -vt 0.051807 0.677083 -vt 0.025904 0.677083 -vt 0.000000 0.666666 -vt 0.000000 0.677083 -vt 0.025904 0.687500 -vt 0.025904 0.697916 -vt 0.000000 0.687500 -vt 0.000000 0.697916 -vt 0.025904 0.708333 -vt 0.051807 0.750000 -vt 0.051807 0.739583 -vt 0.051807 0.729167 -vt 0.051807 0.718750 -vt 0.025904 0.718750 -vt 0.000000 0.708333 -vt 0.000000 0.718750 -vt 0.025904 0.729167 -vt 0.025904 0.739583 -vt 0.000000 0.729167 -vt 0.000000 0.739583 -vt 0.025904 0.750000 -vt 0.207229 0.833334 -vt 0.103615 0.833334 -vt 0.103615 0.812500 -vt 0.207229 0.791667 -vt 0.103615 0.791667 -vt 0.103615 0.770833 -vt 0.051807 0.791667 -vt 0.051807 0.781250 -vt 0.051807 0.770833 -vt 0.051807 0.760417 -vt 0.025904 0.760417 -vt 0.000000 0.750000 -vt 0.000000 0.760417 -vt 0.025904 0.770833 -vt 0.025904 0.781250 -vt 0.000000 0.770833 -vt 0.000000 0.781250 -vt 0.025904 0.791667 -vt 0.051807 0.833334 -vt 0.051807 0.822917 -vt 0.051807 0.812500 -vt 0.051807 0.802084 -vt 0.025904 0.802084 -vt 0.000000 0.791667 -vt 0.000000 0.802084 -vt 0.025904 0.812500 -vt 0.025904 0.822917 -vt 0.000000 0.812500 -vt 0.000000 0.822917 -vt 0.025904 0.833334 -vt 0.103615 0.916667 -vt 0.103615 0.895834 -vt 0.207229 0.875000 -vt 0.103615 0.875000 -vt 0.103615 0.854167 -vt 0.051807 0.875000 -vt 0.051807 0.864584 -vt 0.051807 0.854167 -vt 0.051807 0.843750 -vt 0.025904 0.843750 -vt 0.000000 0.833334 -vt 0.000000 0.843750 -vt 0.025904 0.854167 -vt 0.025904 0.864584 -vt 0.000000 0.854167 -vt 0.000000 0.864584 -vt 0.025904 0.875000 -vt 0.051807 0.916667 -vt 0.051807 0.906250 -vt 0.051807 0.895834 -vt 0.051807 0.885417 -vt 0.025904 0.885417 -vt 0.000000 0.875000 -vt 0.000000 0.885417 -vt 0.025904 0.895834 -vt 0.025904 0.906250 -vt 0.000000 0.895834 -vt 0.000000 0.906250 -vt 0.025904 0.916667 -vt 0.103615 0.958333 -vt 0.207229 1.000000 -vt 0.103615 0.937500 -vt 0.051807 0.958333 -vt 0.051807 0.947917 -vt 0.051807 0.937500 -vt 0.051807 0.927084 -vt 0.025904 0.927084 -vt 0.000000 0.916667 -vt 0.000000 0.927084 -vt 0.025904 0.937500 -vt 0.025904 0.947917 -vt 0.000000 0.937500 -vt 0.000000 0.947917 -vt 0.025904 0.958333 -vt 0.000000 1.000000 -vt 0.000000 0.958333 -vt 0.710046 0.750000 -vt 0.710046 0.833334 -vt 0.646478 0.750000 -vt 0.498684 0.750000 -vt 0.582909 0.750000 -vt 0.582909 0.833334 -vt 0.498684 0.833334 -vt 0.646478 0.833334 -vt 0.498684 0.916667 -vt 0.582909 0.916667 -vt 0.582909 1.000000 -vt 0.498684 1.000000 -vt 0.646478 1.000000 -vt 1.000000 0.583333 -vt 1.000000 0.666666 -vt 0.957053 0.583333 -vt 0.764332 0.583333 -vt 0.818618 0.583333 -vt 0.818618 0.666666 -vt 0.764332 0.666666 -vt 0.866362 0.583333 -vt 0.914105 0.583333 -vt 0.914105 0.666666 -vt 0.866362 0.666666 -vt 0.957053 0.666666 -vt 0.764332 0.916667 -vt 0.818618 0.916667 -vt 0.818618 1.000000 -vt 0.764332 0.750000 -vt 0.818618 0.750000 -vt 0.818618 0.833334 -vt 0.764332 0.833334 -vt 0.764332 1.000000 -vt 1.000000 0.750000 -vt 1.000000 0.833334 -vt 0.957053 0.750000 -vt 0.866362 0.750000 -vt 0.914105 0.750000 -vt 0.914105 0.833334 -vt 0.866362 0.833334 -vt 0.957053 0.833334 -vt 0.866362 0.916667 -vt 0.914105 0.916667 -vt 0.914105 1.000000 -vt 0.866362 1.000000 -vt 0.957053 1.000000 -vt 0.103615 0.000000 -vt 0.103615 0.500000 -vt 0.414458 1.000000 -vt 0.103615 1.000000 -vt 0.051807 1.000000 -vt 0.025904 1.000000 -vn -0.855158 0.138592 0.499497 -vn -0.990337 0.138595 0.004983 -vn -0.855477 0.137445 0.499267 -vn 0.855158 0.138592 -0.499497 -vn 0.990337 0.138595 -0.004983 -vn 0.855477 0.137445 -0.499267 -vn 0.858038 0.119287 -0.499541 -vn 0.992853 0.119290 -0.003582 -vn 0.858835 0.112906 -0.499655 -vn -0.861619 0.119288 -0.493338 -vn -0.499543 0.119288 -0.858037 -vn -0.862116 0.112906 -0.493972 -vn -0.864783 0.062737 -0.498211 -vn -0.522059 0.054243 -0.851183 -vn -0.559013 0.035015 -0.828420 -vn -0.998818 0.048476 0.003588 -vn -0.998889 0.047128 0.000794 -vn -0.864783 0.062737 -0.498211 -vn -0.865986 0.007573 -0.500011 -vn -0.848748 -0.198912 -0.489960 -vn -0.915190 -0.136671 -0.379143 -vn -0.970776 0.085464 -0.224254 -vn -0.946638 -0.198907 -0.253600 -vn -0.982121 -0.136787 -0.129332 -vn -0.946638 -0.198907 -0.253600 -vn -0.753817 -0.625309 -0.201863 -vn -0.820199 -0.548350 -0.163050 -vn -0.982121 -0.136787 -0.129332 -vn -0.773684 -0.625316 -0.101943 -vn -0.834536 -0.548214 -0.054865 -vn -0.834536 -0.548214 -0.054865 -vn -0.773684 -0.625316 -0.101943 -vn -0.199250 -0.979861 -0.013125 -vn -0.195626 -0.976106 0.094593 -vn -0.774567 -0.626221 0.088845 -vn -0.834536 -0.548214 -0.054865 -vn -0.059975 -0.994232 0.088919 -vn -0.195626 -0.976106 0.094593 -vn -0.199250 -0.979861 -0.013125 -vn 0.079824 -0.996795 0.005260 -vn -0.199250 -0.979861 -0.013125 -vn -0.197953 -0.979864 -0.026106 -vn -0.195829 -0.979864 -0.038953 -vn -0.820199 -0.548350 -0.163050 -vn -0.753817 -0.625309 -0.201863 -vn -0.197953 -0.979864 -0.026106 -vn -0.773684 -0.625316 -0.101943 -vn -0.820199 -0.548350 -0.163050 -vn 0.079314 -0.996795 0.010461 -vn -0.197953 -0.979864 -0.026106 -vn -0.195829 -0.979864 -0.038953 -vn 0.078460 -0.996795 0.015609 -vn -0.195829 -0.979864 -0.038953 -vn -0.192889 -0.979859 -0.051676 -vn -0.848748 -0.198912 -0.489960 -vn -0.675878 -0.625313 -0.390093 -vn -0.749973 -0.548375 -0.369898 -vn -0.915190 -0.136671 -0.379143 -vn -0.720908 -0.625314 -0.298787 -vn -0.792045 -0.548040 -0.268918 -vn -0.189096 -0.979856 -0.064228 -vn -0.792045 -0.548040 -0.268918 -vn -0.720908 -0.625314 -0.298787 -vn -0.192889 -0.979859 -0.051676 -vn -0.753817 -0.625309 -0.201863 -vn -0.792045 -0.548040 -0.268918 -vn 0.077272 -0.996795 0.020703 -vn -0.192889 -0.979859 -0.051676 -vn -0.189096 -0.979856 -0.064228 -vn 0.075746 -0.996795 0.025730 -vn -0.189096 -0.979856 -0.064228 -vn -0.184454 -0.979861 -0.076474 -vn -0.179057 -0.979865 -0.088341 -vn -0.749973 -0.548375 -0.369898 -vn -0.675878 -0.625313 -0.390093 -vn -0.184454 -0.979861 -0.076474 -vn -0.720908 -0.625314 -0.298787 -vn -0.749973 -0.548375 -0.369898 -vn 0.073898 -0.996795 0.030640 -vn -0.184454 -0.979861 -0.076474 -vn -0.179057 -0.979865 -0.088341 -vn 0.071742 -0.996795 0.035397 -vn -0.179057 -0.979865 -0.088341 -vn -0.172924 -0.979863 -0.099831 -vn -0.603081 -0.136554 -0.785905 -vn -0.692977 -0.198918 -0.692975 -vn -0.679581 0.085468 -0.728605 -vn -0.679581 0.085468 -0.728605 -vn -0.692977 -0.198918 -0.692975 -vn -0.785908 -0.136554 -0.603077 -vn -0.692977 -0.198918 -0.692975 -vn -0.551796 -0.625317 -0.551816 -vn -0.628648 -0.548296 -0.551520 -vn -0.785908 -0.136554 -0.603077 -vn -0.619062 -0.625306 -0.475137 -vn -0.695502 -0.548117 -0.464591 -vn -0.166042 -0.979858 -0.110944 -vn -0.695502 -0.548117 -0.464591 -vn -0.619062 -0.625306 -0.475137 -vn -0.172924 -0.979863 -0.099831 -vn -0.675878 -0.625313 -0.390093 -vn -0.695502 -0.548117 -0.464591 -vn 0.069281 -0.996795 0.039999 -vn -0.172924 -0.979863 -0.099831 -vn -0.166042 -0.979858 -0.110944 -vn 0.066515 -0.996795 0.044445 -vn -0.166042 -0.979858 -0.110944 -vn -0.158405 -0.979857 -0.121607 -vn -0.150082 -0.979862 -0.131702 -vn -0.628648 -0.548296 -0.551520 -vn -0.551796 -0.625317 -0.551816 -vn -0.158405 -0.979857 -0.121607 -vn -0.619062 -0.625306 -0.475137 -vn -0.628648 -0.548296 -0.551520 -vn 0.063454 -0.996795 0.048715 -vn -0.158405 -0.979857 -0.121607 -vn -0.150082 -0.979862 -0.131702 -vn 0.060129 -0.996795 0.052767 -vn -0.150082 -0.979862 -0.131702 -vn -0.141165 -0.979865 -0.141202 -vn -0.489963 -0.198913 -0.848746 -vn -0.390067 -0.625315 -0.675892 -vn -0.464580 -0.548113 -0.695513 -vn -0.603081 -0.136554 -0.785905 -vn -0.475115 -0.625305 -0.619080 -vn -0.551508 -0.548294 -0.628659 -vn -0.131662 -0.979863 -0.150115 -vn -0.551508 -0.548294 -0.628659 -vn -0.475115 -0.625305 -0.619080 -vn -0.141165 -0.979865 -0.141202 -vn -0.551796 -0.625317 -0.551816 -vn -0.551508 -0.548294 -0.628659 -vn 0.056560 -0.996795 0.056577 -vn -0.141165 -0.979865 -0.141202 -vn -0.131662 -0.979863 -0.150115 -vn 0.052748 -0.996795 0.060144 -vn -0.131662 -0.979863 -0.150115 -vn -0.121566 -0.979857 -0.158438 -vn -0.110900 -0.979858 -0.166071 -vn -0.464580 -0.548113 -0.695513 -vn -0.390067 -0.625315 -0.675892 -vn -0.121566 -0.979857 -0.158438 -vn -0.475115 -0.625305 -0.619080 -vn -0.464580 -0.548113 -0.695513 -vn 0.048696 -0.996795 0.063468 -vn -0.121566 -0.979857 -0.158438 -vn -0.110900 -0.979858 -0.166071 -vn 0.044424 -0.996795 0.066528 -vn -0.110900 -0.979858 -0.166071 -vn -0.099785 -0.979863 -0.172949 -vn -0.862907 0.102956 -0.494765 -vn -0.499945 0.102956 -0.859916 -vn -0.863780 0.089908 -0.495782 -vn -0.995947 0.089909 0.002546 -vn -0.994681 0.102958 0.002990 -vn -0.862907 0.102956 -0.494765 -vn -0.998889 0.047128 0.000794 -vn -0.995947 0.089909 0.002546 -vn -0.863780 0.089908 -0.495782 -vn -0.864783 0.062737 -0.498211 -vn -0.863780 0.089908 -0.495782 -vn -0.500192 0.089907 -0.861234 -vn -0.993600 0.112908 0.003282 -vn -0.992853 0.119290 0.003582 -vn -0.861619 0.119288 -0.493338 -vn -0.994681 0.102958 0.002990 -vn -0.993600 0.112908 0.003282 -vn -0.862116 0.112906 -0.493972 -vn -0.862907 0.102956 -0.494765 -vn -0.862116 0.112906 -0.493972 -vn -0.499657 0.112906 -0.858834 -vn 0.970776 0.085464 -0.224254 -vn 0.865986 0.007573 -0.500011 -vn 0.863839 0.062737 -0.499846 -vn -0.000000 0.054620 -0.998507 -vn -0.000794 0.047128 -0.998889 -vn 0.520588 0.054246 -0.852083 -vn -0.522059 0.054243 -0.851183 -vn -0.000794 0.047128 -0.998889 -vn -0.000000 0.054620 -0.998507 -vn -0.000000 0.054620 -0.998507 -vn 0.000000 -0.198908 -0.980018 -vn -0.129333 -0.136787 -0.982121 -vn -0.224256 0.085466 -0.970775 -vn -0.253603 -0.198906 -0.946637 -vn -0.379146 -0.136670 -0.915188 -vn -0.253603 -0.198906 -0.946637 -vn -0.201834 -0.625309 -0.753825 -vn -0.268901 -0.548039 -0.792052 -vn -0.379146 -0.136670 -0.915188 -vn -0.298761 -0.625313 -0.720920 -vn -0.369884 -0.548374 -0.749982 -vn -0.088294 -0.979865 -0.179080 -vn -0.369884 -0.548374 -0.749982 -vn -0.298761 -0.625313 -0.720920 -vn -0.099785 -0.979863 -0.172949 -vn -0.390067 -0.625315 -0.675892 -vn -0.369884 -0.548374 -0.749982 -vn 0.039978 -0.996795 0.069293 -vn -0.099785 -0.979863 -0.172949 -vn -0.088294 -0.979865 -0.179080 -vn 0.035375 -0.996795 0.071753 -vn -0.088294 -0.979865 -0.179080 -vn -0.076426 -0.979861 -0.184474 -vn -0.064178 -0.979856 -0.189113 -vn -0.268901 -0.548039 -0.792052 -vn -0.201834 -0.625309 -0.753825 -vn -0.076426 -0.979861 -0.184474 -vn -0.298761 -0.625313 -0.720920 -vn -0.268901 -0.548039 -0.792052 -vn 0.030617 -0.996795 0.073907 -vn -0.076426 -0.979861 -0.184474 -vn -0.064178 -0.979856 -0.189113 -vn 0.025707 -0.996795 0.075754 -vn -0.064178 -0.979856 -0.189113 -vn -0.051625 -0.979859 -0.192902 -vn 0.000000 -0.198908 -0.980018 -vn 0.000016 -0.625302 -0.780383 -vn -0.054845 -0.548214 -0.834538 -vn -0.129333 -0.136787 -0.982121 -vn -0.101911 -0.625316 -0.773688 -vn -0.163032 -0.548348 -0.820204 -vn -0.038902 -0.979864 -0.195841 -vn -0.163032 -0.548348 -0.820204 -vn -0.101911 -0.625316 -0.773688 -vn -0.051625 -0.979859 -0.192902 -vn -0.201834 -0.625309 -0.753825 -vn -0.163032 -0.548348 -0.820204 -vn 0.020680 -0.996795 0.077279 -vn -0.051625 -0.979859 -0.192902 -vn -0.038902 -0.979864 -0.195841 -vn 0.015585 -0.996795 0.078466 -vn -0.038902 -0.979864 -0.195841 -vn -0.026053 -0.979864 -0.197959 -vn -0.013072 -0.979860 -0.199255 -vn -0.054845 -0.548214 -0.834538 -vn 0.000016 -0.625302 -0.780383 -vn -0.026053 -0.979864 -0.197959 -vn -0.101911 -0.625316 -0.773688 -vn -0.054845 -0.548214 -0.834538 -vn 0.010437 -0.996795 0.079315 -vn -0.026053 -0.979864 -0.197959 -vn -0.013072 -0.979860 -0.199255 -vn 0.005235 -0.996795 0.079826 -vn -0.013072 -0.979860 -0.199255 -vn 0.000027 -0.979855 -0.199708 -vn 0.559013 0.035015 -0.828420 -vn 0.489963 -0.198913 -0.848746 -vn 0.379146 -0.136670 -0.915188 -vn 0.224256 0.085466 -0.970775 -vn 0.253603 -0.198906 -0.946637 -vn 0.129333 -0.136787 -0.982121 -vn 0.253603 -0.198906 -0.946637 -vn 0.201864 -0.625309 -0.753817 -vn 0.163052 -0.548348 -0.820200 -vn 0.129333 -0.136787 -0.982121 -vn 0.101942 -0.625316 -0.773684 -vn 0.054866 -0.548214 -0.834537 -vn 0.013125 -0.979860 -0.199252 -vn 0.054866 -0.548214 -0.834537 -vn 0.101942 -0.625316 -0.773684 -vn 0.000027 -0.979855 -0.199708 -vn 0.000016 -0.625302 -0.780383 -vn 0.054866 -0.548214 -0.834537 -vn -0.000012 -0.996795 0.079997 -vn 0.000027 -0.979855 -0.199708 -vn 0.013125 -0.979860 -0.199252 -vn -0.005260 -0.996795 0.079825 -vn 0.013125 -0.979860 -0.199252 -vn 0.026105 -0.979864 -0.197952 -vn 0.038954 -0.979864 -0.195830 -vn 0.163052 -0.548348 -0.820200 -vn 0.201864 -0.625309 -0.753817 -vn 0.026105 -0.979864 -0.197952 -vn 0.101942 -0.625316 -0.773684 -vn 0.163052 -0.548348 -0.820200 -vn -0.010461 -0.996795 0.079312 -vn 0.026105 -0.979864 -0.197952 -vn 0.038954 -0.979864 -0.195830 -vn -0.015609 -0.996795 0.078461 -vn 0.038954 -0.979864 -0.195830 -vn 0.051676 -0.979859 -0.192887 -vn 0.489963 -0.198913 -0.848746 -vn 0.390094 -0.625314 -0.675876 -vn 0.369902 -0.548374 -0.749972 -vn 0.379146 -0.136670 -0.915188 -vn 0.298790 -0.625312 -0.720908 -vn 0.268920 -0.548039 -0.792045 -vn 0.064229 -0.979856 -0.189096 -vn 0.268920 -0.548039 -0.792045 -vn 0.298790 -0.625312 -0.720908 -vn 0.051676 -0.979859 -0.192887 -vn 0.201864 -0.625309 -0.753817 -vn 0.268920 -0.548039 -0.792045 -vn -0.020704 -0.996795 0.077272 -vn 0.051676 -0.979859 -0.192887 -vn 0.064229 -0.979856 -0.189096 -vn -0.025730 -0.996795 0.075746 -vn 0.064229 -0.979856 -0.189096 -vn 0.076475 -0.979861 -0.184454 -vn 0.088341 -0.979865 -0.179057 -vn 0.369902 -0.548374 -0.749972 -vn 0.390094 -0.625314 -0.675876 -vn 0.076475 -0.979861 -0.184454 -vn 0.298790 -0.625312 -0.720908 -vn 0.369902 -0.548374 -0.749972 -vn -0.030640 -0.996795 0.073898 -vn 0.076475 -0.979861 -0.184454 -vn 0.088341 -0.979865 -0.179057 -vn -0.035397 -0.996795 0.071742 -vn 0.088341 -0.979865 -0.179057 -vn 0.099830 -0.979863 -0.172922 -vn 0.559013 0.035015 -0.828420 -vn 0.520588 0.054246 -0.852083 -vn 0.863839 0.062737 -0.499846 -vn 0.865986 0.007573 -0.500011 -vn 0.848748 -0.198912 -0.489960 -vn 0.785908 -0.136554 -0.603077 -vn 0.679581 0.085468 -0.728605 -vn 0.692977 -0.198918 -0.692975 -vn 0.603081 -0.136554 -0.785905 -vn 0.692977 -0.198918 -0.692975 -vn 0.551819 -0.625315 -0.551794 -vn 0.551523 -0.548295 -0.628645 -vn 0.603081 -0.136554 -0.785905 -vn 0.475140 -0.625305 -0.619061 -vn 0.464597 -0.548113 -0.695501 -vn 0.110944 -0.979858 -0.166042 -vn 0.464597 -0.548113 -0.695501 -vn 0.475140 -0.625305 -0.619061 -vn 0.099830 -0.979863 -0.172922 -vn 0.390094 -0.625314 -0.675876 -vn 0.464597 -0.548113 -0.695501 -vn -0.039999 -0.996795 0.069281 -vn 0.099830 -0.979863 -0.172922 -vn 0.110944 -0.979858 -0.166042 -vn -0.044445 -0.996795 0.066514 -vn 0.110944 -0.979858 -0.166042 -vn 0.121608 -0.979857 -0.158406 -vn 0.131702 -0.979863 -0.150080 -vn 0.551523 -0.548295 -0.628645 -vn 0.551819 -0.625315 -0.551794 -vn 0.121608 -0.979857 -0.158406 -vn 0.475140 -0.625305 -0.619061 -vn 0.551523 -0.548295 -0.628645 -vn -0.048715 -0.996795 0.063453 -vn 0.121608 -0.979857 -0.158406 -vn 0.131702 -0.979863 -0.150080 -vn -0.052767 -0.996795 0.060128 -vn 0.131702 -0.979863 -0.150080 -vn 0.141203 -0.979865 -0.141164 -vn 0.848748 -0.198912 -0.489960 -vn 0.675893 -0.625315 -0.390065 -vn 0.695513 -0.548117 -0.464574 -vn 0.785908 -0.136554 -0.603077 -vn 0.619082 -0.625304 -0.475112 -vn 0.628661 -0.548296 -0.551504 -vn 0.150116 -0.979863 -0.131661 -vn 0.628661 -0.548296 -0.551504 -vn 0.619082 -0.625304 -0.475112 -vn 0.141203 -0.979865 -0.141164 -vn 0.551819 -0.625315 -0.551794 -vn 0.628661 -0.548296 -0.551504 -vn -0.056577 -0.996795 0.056559 -vn 0.141203 -0.979865 -0.141164 -vn 0.150116 -0.979863 -0.131661 -vn -0.060145 -0.996795 0.052748 -vn 0.150116 -0.979863 -0.131661 -vn 0.158439 -0.979857 -0.121565 -vn 0.166073 -0.979858 -0.110900 -vn 0.695513 -0.548117 -0.464574 -vn 0.675893 -0.625315 -0.390065 -vn 0.158439 -0.979857 -0.121565 -vn 0.619082 -0.625304 -0.475112 -vn 0.695513 -0.548117 -0.464574 -vn -0.063469 -0.996795 0.048696 -vn 0.158439 -0.979857 -0.121565 -vn 0.166073 -0.979858 -0.110900 -vn -0.066529 -0.996795 0.044425 -vn 0.166073 -0.979858 -0.110900 -vn 0.172949 -0.979863 -0.099784 -vn 0.982121 -0.136787 -0.129332 -vn 0.946638 -0.198907 -0.253600 -vn 0.970776 0.085464 -0.224254 -vn 0.970776 0.085464 -0.224254 -vn 0.946638 -0.198907 -0.253600 -vn 0.915190 -0.136671 -0.379143 -vn 0.946638 -0.198907 -0.253600 -vn 0.753824 -0.625311 -0.201832 -vn 0.792052 -0.548040 -0.268898 -vn 0.915190 -0.136671 -0.379143 -vn 0.720921 -0.625312 -0.298759 -vn 0.749983 -0.548375 -0.369880 -vn 0.179081 -0.979865 -0.088293 -vn 0.749983 -0.548375 -0.369880 -vn 0.720921 -0.625312 -0.298759 -vn 0.172949 -0.979863 -0.099784 -vn 0.675893 -0.625315 -0.390065 -vn 0.749983 -0.548375 -0.369880 -vn -0.069293 -0.996795 0.039977 -vn 0.172949 -0.979863 -0.099784 -vn 0.179081 -0.979865 -0.088293 -vn -0.071753 -0.996795 0.035375 -vn 0.179081 -0.979865 -0.088293 -vn 0.184475 -0.979861 -0.076425 -vn 0.189113 -0.979856 -0.064178 -vn 0.792052 -0.548040 -0.268898 -vn 0.753824 -0.625311 -0.201832 -vn 0.184475 -0.979861 -0.076425 -vn 0.720921 -0.625312 -0.298759 -vn 0.792052 -0.548040 -0.268898 -vn -0.073908 -0.996795 0.030617 -vn 0.184475 -0.979861 -0.076425 -vn 0.189113 -0.979856 -0.064178 -vn -0.075754 -0.996795 0.025706 -vn 0.189113 -0.979856 -0.064178 -vn 0.192902 -0.979859 -0.051624 -vn 0.834538 -0.548214 -0.054844 -vn 0.773688 -0.625316 -0.101912 -vn 0.982121 -0.136787 -0.129332 -vn 0.982121 -0.136787 -0.129332 -vn 0.773688 -0.625316 -0.101912 -vn 0.820204 -0.548349 -0.163030 -vn 0.195842 -0.979864 -0.038902 -vn 0.820204 -0.548349 -0.163030 -vn 0.773688 -0.625316 -0.101912 -vn 0.192902 -0.979859 -0.051624 -vn 0.753824 -0.625311 -0.201832 -vn 0.820204 -0.548349 -0.163030 -vn -0.077279 -0.996795 0.020680 -vn 0.192902 -0.979859 -0.051624 -vn 0.195842 -0.979864 -0.038902 -vn -0.078466 -0.996795 0.015585 -vn 0.195842 -0.979864 -0.038902 -vn 0.197959 -0.979864 -0.026053 -vn 0.199256 -0.979860 -0.013072 -vn 0.834538 -0.548214 -0.054844 -vn 0.780383 -0.625302 0.000016 -vn 0.197959 -0.979864 -0.026053 -vn 0.773688 -0.625316 -0.101912 -vn 0.834538 -0.548214 -0.054844 -vn -0.079316 -0.996795 0.010437 -vn 0.197959 -0.979864 -0.026053 -vn 0.199256 -0.979860 -0.013072 -vn -0.079827 -0.996795 0.005235 -vn 0.199256 -0.979860 -0.013072 -vn 0.199709 -0.979855 0.000026 -vn -0.003582 0.119290 -0.992853 -vn 0.493340 0.119288 -0.861618 -vn -0.003282 0.112908 -0.993600 -vn -0.002546 0.089909 -0.995947 -vn -0.002990 0.102958 -0.994681 -vn 0.494767 0.102956 -0.862905 -vn -0.500192 0.089907 -0.861234 -vn -0.499945 0.102956 -0.859916 -vn -0.002990 0.102958 -0.994681 -vn -0.522059 0.054243 -0.851183 -vn -0.500192 0.089907 -0.861234 -vn -0.002546 0.089909 -0.995947 -vn -0.000794 0.047128 -0.998889 -vn -0.002546 0.089909 -0.995947 -vn 0.495785 0.089908 -0.863779 -vn -0.499543 0.119288 -0.858037 -vn -0.003582 0.119290 -0.992853 -vn -0.499657 0.112906 -0.858834 -vn -0.499945 0.102956 -0.859916 -vn -0.499657 0.112906 -0.858834 -vn -0.003282 0.112908 -0.993600 -vn -0.002990 0.102958 -0.994681 -vn -0.003282 0.112908 -0.993600 -vn 0.493974 0.112906 -0.862115 -vn 0.861235 0.089907 -0.500190 -vn 0.859917 0.102956 -0.499943 -vn 0.994681 0.102958 -0.002990 -vn 0.495785 0.089908 -0.863779 -vn 0.494767 0.102956 -0.862905 -vn 0.859917 0.102956 -0.499943 -vn 0.520588 0.054246 -0.852083 -vn 0.495785 0.089908 -0.863779 -vn 0.861235 0.089907 -0.500190 -vn 0.863839 0.062737 -0.499846 -vn 0.861235 0.089907 -0.500190 -vn 0.995947 0.089909 -0.002546 -vn 0.493340 0.119288 -0.861618 -vn 0.858038 0.119287 -0.499541 -vn 0.493974 0.112906 -0.862115 -vn 0.494767 0.102956 -0.862905 -vn 0.493974 0.112906 -0.862115 -vn 0.858835 0.112906 -0.499655 -vn 0.859917 0.102956 -0.499943 -vn 0.858835 0.112906 -0.499655 -vn 0.993600 0.112908 -0.003282 -vn -0.860140 0.138592 -0.490867 -vn -0.499499 0.138592 -0.855157 -vn -0.860102 0.137445 -0.491258 -vn -0.860841 0.128646 -0.492344 -vn -0.499366 0.128646 -0.856787 -vn -0.861162 0.124651 -0.492811 -vn -0.992193 0.124653 0.003810 -vn -0.991682 0.128649 0.004054 -vn -0.860841 0.128646 -0.492344 -vn -0.992853 0.119290 0.003582 -vn -0.992193 0.124653 0.003810 -vn -0.861162 0.124651 -0.492811 -vn -0.861619 0.119288 -0.493338 -vn -0.861162 0.124651 -0.492811 -vn -0.499410 0.124651 -0.857352 -vn -0.860318 0.134936 -0.491574 -vn -0.499299 0.134937 -0.855858 -vn -0.860532 0.132157 -0.491955 -vn -0.991220 0.132159 0.004236 -vn -0.990844 0.134939 0.004460 -vn -0.860318 0.134936 -0.491574 -vn -0.991682 0.128649 0.004054 -vn -0.991220 0.132159 0.004236 -vn -0.860532 0.132157 -0.491955 -vn -0.860841 0.128646 -0.492344 -vn -0.860532 0.132157 -0.491955 -vn -0.499292 0.132157 -0.856295 -vn -0.990498 0.137448 0.004625 -vn -0.990337 0.138595 0.004983 -vn -0.860140 0.138592 -0.490867 -vn -0.990844 0.134939 0.004460 -vn -0.990498 0.137448 0.004625 -vn -0.860102 0.137445 -0.491258 -vn -0.860318 0.134936 -0.491574 -vn -0.860102 0.137445 -0.491258 -vn -0.499269 0.137445 -0.855476 -vn 0.857353 0.124650 -0.499408 -vn 0.856788 0.128646 -0.499364 -vn 0.991682 0.128649 -0.004054 -vn -0.003810 0.124653 -0.992193 -vn -0.004054 0.128649 -0.991682 -vn 0.492346 0.128646 -0.860840 -vn -0.499410 0.124651 -0.857352 -vn -0.499366 0.128646 -0.856787 -vn -0.004054 0.128649 -0.991682 -vn -0.499543 0.119288 -0.858037 -vn -0.499410 0.124651 -0.857352 -vn -0.003810 0.124653 -0.992193 -vn -0.003582 0.119290 -0.992853 -vn -0.003810 0.124653 -0.992193 -vn 0.492814 0.124651 -0.861160 -vn 0.492814 0.124651 -0.861160 -vn 0.492346 0.128646 -0.860840 -vn 0.856788 0.128646 -0.499364 -vn 0.493340 0.119288 -0.861618 -vn 0.492814 0.124651 -0.861160 -vn 0.857353 0.124650 -0.499408 -vn 0.858038 0.119287 -0.499541 -vn 0.857353 0.124650 -0.499408 -vn 0.992193 0.124653 -0.003810 -vn -0.004983 0.138595 -0.990337 -vn 0.490869 0.138592 -0.860139 -vn -0.004625 0.137448 -0.990498 -vn -0.004236 0.132159 -0.991220 -vn -0.004460 0.134939 -0.990844 -vn 0.491576 0.134936 -0.860317 -vn -0.499292 0.132157 -0.856295 -vn -0.499299 0.134937 -0.855858 -vn -0.004460 0.134939 -0.990844 -vn -0.499366 0.128646 -0.856787 -vn -0.499292 0.132157 -0.856295 -vn -0.004236 0.132159 -0.991220 -vn -0.004054 0.128649 -0.991682 -vn -0.004236 0.132159 -0.991220 -vn 0.491957 0.132157 -0.860530 -vn -0.499499 0.138592 -0.855157 -vn -0.004983 0.138595 -0.990337 -vn -0.499269 0.137445 -0.855476 -vn -0.499299 0.134937 -0.855858 -vn -0.499269 0.137445 -0.855476 -vn -0.004625 0.137448 -0.990498 -vn -0.004460 0.134939 -0.990844 -vn -0.004625 0.137448 -0.990498 -vn 0.491260 0.137445 -0.860100 -vn 0.856296 0.132157 -0.499291 -vn 0.855859 0.134936 -0.499297 -vn 0.990844 0.134939 -0.004460 -vn 0.491957 0.132157 -0.860530 -vn 0.491576 0.134936 -0.860317 -vn 0.855859 0.134936 -0.499297 -vn 0.492346 0.128646 -0.860840 -vn 0.491957 0.132157 -0.860530 -vn 0.856296 0.132157 -0.499291 -vn 0.856788 0.128646 -0.499364 -vn 0.856296 0.132157 -0.499291 -vn 0.991220 0.132159 -0.004236 -vn 0.490869 0.138592 -0.860139 -vn 0.855158 0.138592 -0.499497 -vn 0.491260 0.137445 -0.860100 -vn 0.491576 0.134936 -0.860317 -vn 0.491260 0.137445 -0.860100 -vn 0.855477 0.137445 -0.499267 -vn 0.855859 0.134936 -0.499297 -vn 0.855477 0.137445 -0.499267 -vn 0.990498 0.137448 -0.004625 -vn -0.858835 0.112906 0.499655 -vn -0.858038 0.119288 0.499541 -vn -0.992853 0.119290 0.003582 -vn 0.861619 0.119288 0.493338 -vn 0.499543 0.119288 0.858037 -vn 0.862116 0.112906 0.493972 -vn 0.864783 0.062737 0.498211 -vn 0.522059 0.054243 0.851183 -vn 0.559013 0.035015 0.828420 -vn 0.998507 0.054619 0.000000 -vn 0.998889 0.047128 -0.000794 -vn 0.864783 0.062737 0.498211 -vn 0.865986 0.007573 0.500011 -vn 0.848748 -0.198912 0.489960 -vn 0.915190 -0.136671 0.379143 -vn 0.970776 0.085464 0.224254 -vn 0.946638 -0.198907 0.253600 -vn 0.982121 -0.136787 0.129332 -vn 0.946638 -0.198907 0.253600 -vn 0.753817 -0.625309 0.201863 -vn 0.820199 -0.548350 0.163050 -vn 0.982121 -0.136787 0.129332 -vn 0.773684 -0.625316 0.101943 -vn 0.834536 -0.548215 0.054865 -vn 0.199250 -0.979861 0.013125 -vn 0.834536 -0.548215 0.054865 -vn 0.773684 -0.625316 0.101943 -vn 0.199709 -0.979855 0.000026 -vn 0.780383 -0.625302 0.000016 -vn 0.834536 -0.548215 0.054865 -vn -0.079997 -0.996795 -0.000012 -vn 0.199709 -0.979855 0.000026 -vn 0.199250 -0.979861 0.013125 -vn -0.079824 -0.996795 -0.005260 -vn 0.199250 -0.979861 0.013125 -vn 0.197953 -0.979864 0.026106 -vn 0.195829 -0.979864 0.038953 -vn 0.820199 -0.548350 0.163050 -vn 0.753817 -0.625309 0.201863 -vn 0.197953 -0.979864 0.026106 -vn 0.773684 -0.625316 0.101943 -vn 0.820199 -0.548350 0.163050 -vn -0.079314 -0.996795 -0.010461 -vn 0.197953 -0.979864 0.026106 -vn 0.195829 -0.979864 0.038953 -vn -0.078460 -0.996795 -0.015609 -vn 0.195829 -0.979864 0.038953 -vn 0.192889 -0.979859 0.051676 -vn 0.848748 -0.198912 0.489960 -vn 0.675878 -0.625313 0.390093 -vn 0.749973 -0.548375 0.369898 -vn 0.915190 -0.136671 0.379143 -vn 0.720908 -0.625314 0.298787 -vn 0.792045 -0.548040 0.268918 -vn 0.189096 -0.979856 0.064228 -vn 0.792045 -0.548040 0.268918 -vn 0.720908 -0.625314 0.298787 -vn 0.192889 -0.979859 0.051676 -vn 0.753817 -0.625309 0.201863 -vn 0.792045 -0.548040 0.268918 -vn -0.077272 -0.996795 -0.020703 -vn 0.192889 -0.979859 0.051676 -vn 0.189096 -0.979856 0.064228 -vn -0.075746 -0.996795 -0.025730 -vn 0.189096 -0.979856 0.064228 -vn 0.184454 -0.979861 0.076474 -vn 0.179057 -0.979865 0.088341 -vn 0.749973 -0.548375 0.369898 -vn 0.675878 -0.625313 0.390093 -vn 0.184454 -0.979861 0.076474 -vn 0.720908 -0.625314 0.298787 -vn 0.749973 -0.548375 0.369898 -vn -0.073898 -0.996795 -0.030640 -vn 0.184454 -0.979861 0.076474 -vn 0.179057 -0.979865 0.088341 -vn -0.071742 -0.996795 -0.035397 -vn 0.179057 -0.979865 0.088341 -vn 0.172924 -0.979863 0.099831 -vn 0.559013 0.035015 0.828420 -vn 0.489963 -0.198913 0.848746 -vn 0.603081 -0.136554 0.785905 -vn 0.679581 0.085468 0.728605 -vn 0.692977 -0.198918 0.692975 -vn 0.785908 -0.136554 0.603077 -vn 0.692977 -0.198918 0.692975 -vn 0.551796 -0.625317 0.551816 -vn 0.628648 -0.548296 0.551520 -vn 0.785908 -0.136554 0.603077 -vn 0.619062 -0.625306 0.475137 -vn 0.695502 -0.548117 0.464591 -vn 0.166042 -0.979858 0.110944 -vn 0.695502 -0.548117 0.464591 -vn 0.619062 -0.625306 0.475137 -vn 0.172924 -0.979863 0.099831 -vn 0.675878 -0.625313 0.390093 -vn 0.695502 -0.548117 0.464591 -vn -0.069281 -0.996795 -0.039999 -vn 0.172924 -0.979863 0.099831 -vn 0.166042 -0.979858 0.110944 -vn -0.066515 -0.996795 -0.044445 -vn 0.166042 -0.979858 0.110944 -vn 0.158405 -0.979857 0.121607 -vn 0.150082 -0.979862 0.131702 -vn 0.628648 -0.548296 0.551520 -vn 0.551796 -0.625317 0.551816 -vn 0.158405 -0.979857 0.121607 -vn 0.619062 -0.625306 0.475137 -vn 0.628648 -0.548296 0.551520 -vn -0.063454 -0.996795 -0.048715 -vn 0.158405 -0.979857 0.121607 -vn 0.150082 -0.979862 0.131702 -vn -0.060129 -0.996795 -0.052767 -vn 0.150082 -0.979862 0.131702 -vn 0.141165 -0.979865 0.141202 -vn 0.489963 -0.198913 0.848746 -vn 0.390067 -0.625315 0.675892 -vn 0.464580 -0.548113 0.695513 -vn 0.603081 -0.136554 0.785905 -vn 0.475115 -0.625305 0.619080 -vn 0.551508 -0.548294 0.628659 -vn 0.131662 -0.979863 0.150115 -vn 0.551508 -0.548294 0.628659 -vn 0.475115 -0.625305 0.619080 -vn 0.141165 -0.979865 0.141202 -vn 0.551796 -0.625317 0.551816 -vn 0.551508 -0.548294 0.628659 -vn -0.056560 -0.996795 -0.056577 -vn 0.141165 -0.979865 0.141202 -vn 0.131662 -0.979863 0.150115 -vn -0.052748 -0.996795 -0.060144 -vn 0.131662 -0.979863 0.150115 -vn 0.121566 -0.979857 0.158438 -vn 0.110900 -0.979858 0.166071 -vn 0.464580 -0.548113 0.695513 -vn 0.390067 -0.625315 0.675892 -vn 0.121566 -0.979857 0.158438 -vn 0.475115 -0.625305 0.619080 -vn 0.464580 -0.548113 0.695513 -vn -0.048696 -0.996795 -0.063468 -vn 0.121566 -0.979857 0.158438 -vn 0.110900 -0.979858 0.166071 -vn -0.044424 -0.996795 -0.066528 -vn 0.110900 -0.979858 0.166071 -vn 0.099785 -0.979863 0.172949 -vn 0.862907 0.102956 0.494765 -vn 0.499945 0.102956 0.859916 -vn 0.863780 0.089908 0.495782 -vn 0.995947 0.089909 -0.002546 -vn 0.994681 0.102958 -0.002990 -vn 0.862907 0.102956 0.494765 -vn 0.998889 0.047128 -0.000794 -vn 0.995947 0.089909 -0.002546 -vn 0.863780 0.089908 0.495782 -vn 0.864783 0.062737 0.498211 -vn 0.863780 0.089908 0.495782 -vn 0.500192 0.089907 0.861234 -vn 0.993600 0.112908 -0.003282 -vn 0.992853 0.119290 -0.003582 -vn 0.861619 0.119288 0.493338 -vn 0.994681 0.102958 -0.002990 -vn 0.993600 0.112908 -0.003282 -vn 0.862116 0.112906 0.493972 -vn 0.862907 0.102956 0.494765 -vn 0.862116 0.112906 0.493972 -vn 0.499657 0.112906 0.858834 -vn -0.972486 0.075824 0.220276 -vn -0.865986 0.007573 0.500011 -vn -0.863839 0.062737 0.499846 -vn 0.000000 0.054620 0.998507 -vn 0.000794 0.047128 0.998889 -vn -0.520588 0.054246 0.852083 -vn 0.522059 0.054243 0.851183 -vn 0.000794 0.047128 0.998889 -vn 0.000000 0.054620 0.998507 -vn 0.000000 0.054620 0.998507 -vn 0.000000 -0.198908 0.980018 -vn 0.129333 -0.136787 0.982121 -vn 0.224256 0.085466 0.970775 -vn 0.253603 -0.198906 0.946637 -vn 0.379146 -0.136670 0.915188 -vn 0.253603 -0.198906 0.946637 -vn 0.201834 -0.625309 0.753825 -vn 0.268901 -0.548039 0.792052 -vn 0.379146 -0.136670 0.915188 -vn 0.298761 -0.625313 0.720920 -vn 0.369884 -0.548374 0.749982 -vn 0.088294 -0.979865 0.179080 -vn 0.369884 -0.548374 0.749982 -vn 0.298761 -0.625313 0.720920 -vn 0.099785 -0.979863 0.172949 -vn 0.390067 -0.625315 0.675892 -vn 0.369884 -0.548374 0.749982 -vn -0.039978 -0.996795 -0.069293 -vn 0.099785 -0.979863 0.172949 -vn 0.088294 -0.979865 0.179080 -vn -0.035375 -0.996795 -0.071753 -vn 0.088294 -0.979865 0.179080 -vn 0.076426 -0.979861 0.184474 -vn 0.064178 -0.979856 0.189113 -vn 0.268901 -0.548039 0.792052 -vn 0.201834 -0.625309 0.753825 -vn 0.076426 -0.979861 0.184474 -vn 0.298761 -0.625313 0.720920 -vn 0.268901 -0.548039 0.792052 -vn -0.030617 -0.996795 -0.073907 -vn 0.076426 -0.979861 0.184474 -vn 0.064178 -0.979856 0.189113 -vn -0.025707 -0.996795 -0.075754 -vn 0.064178 -0.979856 0.189113 -vn 0.051625 -0.979859 0.192902 -vn 0.000000 -0.198908 0.980018 -vn -0.000016 -0.625302 0.780383 -vn 0.054845 -0.548214 0.834538 -vn 0.129333 -0.136787 0.982121 -vn 0.101911 -0.625316 0.773688 -vn 0.163032 -0.548348 0.820204 -vn 0.038902 -0.979864 0.195841 -vn 0.163032 -0.548348 0.820204 -vn 0.101911 -0.625316 0.773688 -vn 0.051625 -0.979859 0.192902 -vn 0.201834 -0.625309 0.753825 -vn 0.163032 -0.548348 0.820204 -vn -0.020680 -0.996795 -0.077279 -vn 0.051625 -0.979859 0.192902 -vn 0.038902 -0.979864 0.195841 -vn -0.015585 -0.996795 -0.078466 -vn 0.038902 -0.979864 0.195841 -vn 0.026053 -0.979864 0.197959 -vn 0.013072 -0.979860 0.199255 -vn 0.054845 -0.548214 0.834538 -vn -0.000016 -0.625302 0.780383 -vn 0.026053 -0.979864 0.197959 -vn 0.101911 -0.625316 0.773688 -vn 0.054845 -0.548214 0.834538 -vn -0.010437 -0.996795 -0.079315 -vn 0.026053 -0.979864 0.197959 -vn 0.013072 -0.979860 0.199255 -vn -0.005235 -0.996795 -0.079826 -vn 0.013072 -0.979860 0.199255 -vn -0.000027 -0.979855 0.199708 -vn -0.559013 0.035015 0.828420 -vn -0.489963 -0.198913 0.848746 -vn -0.379146 -0.136670 0.915188 -vn -0.224256 0.085466 0.970775 -vn -0.253603 -0.198906 0.946637 -vn -0.129333 -0.136787 0.982121 -vn -0.253603 -0.198906 0.946637 -vn -0.201864 -0.625309 0.753817 -vn -0.163052 -0.548348 0.820200 -vn -0.129333 -0.136787 0.982121 -vn -0.101942 -0.625316 0.773684 -vn -0.054866 -0.548214 0.834537 -vn -0.013125 -0.979860 0.199252 -vn -0.054866 -0.548214 0.834537 -vn -0.101942 -0.625316 0.773684 -vn -0.000027 -0.979855 0.199708 -vn -0.000016 -0.625302 0.780383 -vn -0.054866 -0.548214 0.834537 -vn 0.000012 -0.996795 -0.079997 -vn -0.000027 -0.979855 0.199708 -vn -0.013125 -0.979860 0.199252 -vn 0.005260 -0.996795 -0.079825 -vn -0.013125 -0.979860 0.199252 -vn -0.026105 -0.979864 0.197952 -vn -0.038954 -0.979864 0.195830 -vn -0.163052 -0.548348 0.820200 -vn -0.201864 -0.625309 0.753817 -vn -0.026105 -0.979864 0.197952 -vn -0.101942 -0.625316 0.773684 -vn -0.163052 -0.548348 0.820200 -vn 0.010461 -0.996795 -0.079312 -vn -0.026105 -0.979864 0.197952 -vn -0.038954 -0.979864 0.195830 -vn 0.015609 -0.996795 -0.078461 -vn -0.038954 -0.979864 0.195830 -vn -0.051676 -0.979859 0.192887 -vn -0.489963 -0.198913 0.848746 -vn -0.390094 -0.625314 0.675876 -vn -0.369902 -0.548374 0.749972 -vn -0.379146 -0.136670 0.915188 -vn -0.298790 -0.625312 0.720908 -vn -0.268920 -0.548039 0.792045 -vn -0.064229 -0.979856 0.189096 -vn -0.268920 -0.548039 0.792045 -vn -0.298790 -0.625312 0.720908 -vn -0.051676 -0.979859 0.192887 -vn -0.201864 -0.625309 0.753817 -vn -0.268920 -0.548039 0.792045 -vn 0.020704 -0.996795 -0.077272 -vn -0.051676 -0.979859 0.192887 -vn -0.064229 -0.979856 0.189096 -vn 0.025730 -0.996795 -0.075746 -vn -0.064229 -0.979856 0.189096 -vn -0.076475 -0.979861 0.184454 -vn -0.088341 -0.979865 0.179057 -vn -0.369902 -0.548374 0.749972 -vn -0.390094 -0.625314 0.675876 -vn -0.076475 -0.979861 0.184454 -vn -0.298790 -0.625312 0.720908 -vn -0.369902 -0.548374 0.749972 -vn 0.030640 -0.996795 -0.073898 -vn -0.076475 -0.979861 0.184454 -vn -0.088341 -0.979865 0.179057 -vn 0.035397 -0.996795 -0.071742 -vn -0.088341 -0.979865 0.179057 -vn -0.099830 -0.979863 0.172922 -vn -0.559013 0.035015 0.828420 -vn -0.520588 0.054246 0.852083 -vn -0.863839 0.062737 0.499846 -vn -0.865986 0.007573 0.500011 -vn -0.848748 -0.198912 0.489960 -vn -0.785908 -0.136554 0.603077 -vn -0.679581 0.085468 0.728605 -vn -0.692977 -0.198918 0.692975 -vn -0.603081 -0.136554 0.785905 -vn -0.692977 -0.198918 0.692975 -vn -0.551819 -0.625315 0.551794 -vn -0.551523 -0.548295 0.628645 -vn -0.603081 -0.136554 0.785905 -vn -0.475140 -0.625305 0.619061 -vn -0.464597 -0.548113 0.695501 -vn -0.110944 -0.979858 0.166042 -vn -0.464597 -0.548113 0.695501 -vn -0.475140 -0.625305 0.619061 -vn -0.099830 -0.979863 0.172922 -vn -0.390094 -0.625314 0.675876 -vn -0.464597 -0.548113 0.695501 -vn 0.039999 -0.996795 -0.069281 -vn -0.099830 -0.979863 0.172922 -vn -0.110944 -0.979858 0.166042 -vn 0.044445 -0.996795 -0.066514 -vn -0.110944 -0.979858 0.166042 -vn -0.121608 -0.979857 0.158406 -vn -0.131702 -0.979863 0.150080 -vn -0.551523 -0.548295 0.628645 -vn -0.551819 -0.625315 0.551794 -vn -0.121608 -0.979857 0.158406 -vn -0.475140 -0.625305 0.619061 -vn -0.551523 -0.548295 0.628645 -vn 0.048715 -0.996795 -0.063453 -vn -0.121608 -0.979857 0.158406 -vn -0.131702 -0.979863 0.150080 -vn 0.052767 -0.996795 -0.060128 -vn -0.131702 -0.979863 0.150080 -vn -0.141203 -0.979865 0.141164 -vn -0.848748 -0.198912 0.489960 -vn -0.675893 -0.625315 0.390065 -vn -0.695513 -0.548117 0.464574 -vn -0.785908 -0.136554 0.603077 -vn -0.619082 -0.625304 0.475112 -vn -0.628661 -0.548296 0.551504 -vn -0.150116 -0.979863 0.131661 -vn -0.628661 -0.548296 0.551504 -vn -0.619082 -0.625304 0.475112 -vn -0.141203 -0.979865 0.141164 -vn -0.551819 -0.625315 0.551794 -vn -0.628661 -0.548296 0.551504 -vn 0.056577 -0.996795 -0.056559 -vn -0.141203 -0.979865 0.141164 -vn -0.150116 -0.979863 0.131661 -vn 0.060145 -0.996795 -0.052748 -vn -0.150116 -0.979863 0.131661 -vn -0.158439 -0.979857 0.121565 -vn -0.166073 -0.979858 0.110900 -vn -0.695513 -0.548117 0.464574 -vn -0.675893 -0.625315 0.390065 -vn -0.158439 -0.979857 0.121565 -vn -0.619082 -0.625304 0.475112 -vn -0.695513 -0.548117 0.464574 -vn 0.063469 -0.996795 -0.048696 -vn -0.158439 -0.979857 0.121565 -vn -0.166073 -0.979858 0.110900 -vn 0.066529 -0.996795 -0.044425 -vn -0.166073 -0.979858 0.110900 -vn -0.172949 -0.979863 0.099784 -vn -0.959759 -0.214953 0.180714 -vn -0.972486 0.075824 0.220276 -vn -0.998818 0.048476 0.003588 -vn -0.972486 0.075824 0.220276 -vn -0.959759 -0.214953 0.180714 -vn -0.915190 -0.136671 0.379143 -vn -0.959759 -0.214953 0.180714 -vn -0.787262 -0.610234 0.088501 -vn -0.792052 -0.548040 0.268898 -vn -0.915190 -0.136671 0.379143 -vn -0.720921 -0.625312 0.298759 -vn -0.749983 -0.548375 0.369880 -vn -0.179081 -0.979865 0.088293 -vn -0.749983 -0.548375 0.369880 -vn -0.720921 -0.625312 0.298759 -vn -0.172949 -0.979863 0.099784 -vn -0.675893 -0.625315 0.390065 -vn -0.749983 -0.548375 0.369880 -vn 0.069293 -0.996795 -0.039977 -vn -0.172949 -0.979863 0.099784 -vn -0.179081 -0.979865 0.088293 -vn 0.071753 -0.996795 -0.035375 -vn -0.179081 -0.979865 0.088293 -vn -0.184475 -0.979861 0.076425 -vn -0.189113 -0.979856 0.064178 -vn -0.792052 -0.548040 0.268898 -vn -0.787262 -0.610234 0.088501 -vn -0.184475 -0.979861 0.076425 -vn -0.720921 -0.625312 0.298759 -vn -0.792052 -0.548040 0.268898 -vn 0.073908 -0.996795 -0.030617 -vn -0.184475 -0.979861 0.076425 -vn -0.189113 -0.979856 0.064178 -vn 0.075754 -0.996795 -0.025706 -vn -0.189113 -0.979856 0.064178 -vn -0.217514 -0.975719 0.025702 -vn -0.059975 -0.994232 0.088919 -vn 0.079340 -0.996763 -0.012975 -vn -0.217514 -0.975719 0.025702 -vn 0.003582 0.119290 0.992853 -vn -0.493340 0.119288 0.861618 -vn 0.003282 0.112908 0.993600 -vn 0.002546 0.089909 0.995947 -vn 0.002990 0.102958 0.994681 -vn -0.494767 0.102956 0.862905 -vn 0.500192 0.089907 0.861234 -vn 0.499945 0.102956 0.859916 -vn 0.002990 0.102958 0.994681 -vn 0.522059 0.054243 0.851183 -vn 0.500192 0.089907 0.861234 -vn 0.002546 0.089909 0.995947 -vn 0.000794 0.047128 0.998889 -vn 0.002546 0.089909 0.995947 -vn -0.495785 0.089908 0.863779 -vn 0.499657 0.112906 0.858834 -vn 0.499543 0.119288 0.858037 -vn 0.003582 0.119290 0.992853 -vn 0.499945 0.102956 0.859916 -vn 0.499657 0.112906 0.858834 -vn 0.003282 0.112908 0.993600 -vn 0.002990 0.102958 0.994681 -vn 0.003282 0.112908 0.993600 -vn -0.493974 0.112906 0.862115 -vn -0.861235 0.089907 0.500190 -vn -0.859917 0.102956 0.499943 -vn -0.994681 0.102958 0.002990 -vn -0.495785 0.089908 0.863779 -vn -0.494767 0.102956 0.862905 -vn -0.859917 0.102956 0.499943 -vn -0.520588 0.054246 0.852083 -vn -0.495785 0.089908 0.863779 -vn -0.861235 0.089907 0.500190 -vn -0.863839 0.062737 0.499846 -vn -0.861235 0.089907 0.500190 -vn -0.995947 0.089909 0.002546 -vn -0.493974 0.112906 0.862115 -vn -0.493340 0.119288 0.861618 -vn -0.858038 0.119288 0.499541 -vn -0.494767 0.102956 0.862905 -vn -0.493974 0.112906 0.862115 -vn -0.858835 0.112906 0.499655 -vn -0.859917 0.102956 0.499943 -vn -0.858835 0.112906 0.499655 -vn -0.993600 0.112908 0.003282 -vn 0.860140 0.138592 0.490867 -vn 0.499499 0.138592 0.855157 -vn 0.860102 0.137445 0.491258 -vn 0.861162 0.124651 0.492811 -vn 0.860841 0.128646 0.492344 -vn 0.499366 0.128646 0.856787 -vn 0.992193 0.124653 -0.003810 -vn 0.991682 0.128649 -0.004054 -vn 0.860841 0.128646 0.492344 -vn 0.992853 0.119290 -0.003582 -vn 0.992193 0.124653 -0.003810 -vn 0.861162 0.124651 0.492811 -vn 0.861619 0.119288 0.493338 -vn 0.861162 0.124651 0.492811 -vn 0.499410 0.124651 0.857352 -vn 0.860531 0.132157 0.491956 -vn 0.860318 0.134936 0.491574 -vn 0.499299 0.134937 0.855858 -vn 0.991220 0.132159 -0.004236 -vn 0.990844 0.134939 -0.004460 -vn 0.860318 0.134936 0.491574 -vn 0.991682 0.128649 -0.004054 -vn 0.991220 0.132159 -0.004236 -vn 0.860531 0.132157 0.491956 -vn 0.860841 0.128646 0.492344 -vn 0.860531 0.132157 0.491956 -vn 0.499292 0.132157 0.856295 -vn 0.990337 0.138595 -0.004983 -vn 0.860140 0.138592 0.490867 -vn 0.990498 0.137448 -0.004625 -vn 0.990844 0.134939 -0.004460 -vn 0.990498 0.137448 -0.004625 -vn 0.860102 0.137445 0.491258 -vn 0.860318 0.134936 0.491574 -vn 0.860102 0.137445 0.491258 -vn 0.499269 0.137445 0.855476 -vn -0.857353 0.124650 0.499408 -vn -0.856788 0.128646 0.499364 -vn -0.991682 0.128649 0.004054 -vn 0.003810 0.124653 0.992193 -vn 0.004054 0.128649 0.991682 -vn -0.492346 0.128646 0.860840 -vn 0.499410 0.124651 0.857352 -vn 0.499366 0.128646 0.856787 -vn 0.004054 0.128649 0.991682 -vn 0.499543 0.119288 0.858037 -vn 0.499410 0.124651 0.857352 -vn 0.003810 0.124653 0.992193 -vn 0.003582 0.119290 0.992853 -vn 0.003810 0.124653 0.992193 -vn -0.492814 0.124651 0.861160 -vn -0.492814 0.124651 0.861160 -vn -0.492346 0.128646 0.860840 -vn -0.856788 0.128646 0.499364 -vn -0.493340 0.119288 0.861618 -vn -0.492814 0.124651 0.861160 -vn -0.857353 0.124650 0.499408 -vn -0.858038 0.119288 0.499541 -vn -0.857353 0.124650 0.499408 -vn -0.992193 0.124653 0.003810 -vn 0.004983 0.138595 0.990337 -vn -0.490869 0.138592 0.860139 -vn 0.004625 0.137448 0.990498 -vn 0.004236 0.132159 0.991220 -vn 0.004460 0.134939 0.990844 -vn -0.491576 0.134936 0.860317 -vn 0.499292 0.132157 0.856295 -vn 0.499299 0.134937 0.855858 -vn 0.004460 0.134939 0.990844 -vn 0.499366 0.128646 0.856787 -vn 0.499292 0.132157 0.856295 -vn 0.004236 0.132159 0.991220 -vn 0.004054 0.128649 0.991682 -vn 0.004236 0.132159 0.991220 -vn -0.491957 0.132157 0.860530 -vn 0.499499 0.138592 0.855157 -vn 0.004983 0.138595 0.990337 -vn 0.499269 0.137445 0.855476 -vn 0.499299 0.134937 0.855858 -vn 0.499269 0.137445 0.855476 -vn 0.004625 0.137448 0.990498 -vn 0.004460 0.134939 0.990844 -vn 0.004625 0.137448 0.990498 -vn -0.491260 0.137445 0.860100 -vn -0.856296 0.132157 0.499291 -vn -0.855859 0.134936 0.499297 -vn -0.990844 0.134939 0.004460 -vn -0.491957 0.132157 0.860530 -vn -0.491576 0.134936 0.860317 -vn -0.855859 0.134936 0.499297 -vn -0.492346 0.128646 0.860840 -vn -0.491957 0.132157 0.860530 -vn -0.856296 0.132157 0.499291 -vn -0.856788 0.128646 0.499364 -vn -0.856296 0.132157 0.499291 -vn -0.991220 0.132159 0.004236 -vn -0.490869 0.138592 0.860139 -vn -0.855158 0.138592 0.499497 -vn -0.491260 0.137445 0.860100 -vn -0.491576 0.134936 0.860317 -vn -0.491260 0.137445 0.860100 -vn -0.855477 0.137445 0.499267 -vn -0.855859 0.134936 0.499297 -vn -0.855477 0.137445 0.499267 -vn -0.990498 0.137448 0.004625 -vn -0.990337 0.138595 0.004983 -vn -0.990498 0.137448 0.004625 -vn -0.855477 0.137445 0.499267 -vn 0.990337 0.138595 -0.004983 -vn 0.990498 0.137448 -0.004625 -vn 0.855477 0.137445 -0.499267 -vn 0.992853 0.119290 -0.003582 -vn 0.993600 0.112908 -0.003282 -vn 0.858835 0.112906 -0.499655 -vn -0.499543 0.119288 -0.858037 -vn -0.499657 0.112906 -0.858834 -vn -0.862116 0.112906 -0.493972 -vn -0.679581 0.085468 -0.728605 -vn -0.865986 0.007573 -0.500011 -vn -0.864783 0.062737 -0.498211 -vn -0.864783 0.062737 -0.498211 -vn -0.559013 0.035015 -0.828420 -vn -0.679581 0.085468 -0.728605 -vn -0.864783 0.062737 -0.498211 -vn -0.865986 0.007573 -0.500011 -vn -0.970776 0.085464 -0.224254 -vn -0.970776 0.085464 -0.224254 -vn -0.998818 0.048476 0.003588 -vn -0.864783 0.062737 -0.498211 -vn -0.915190 -0.136671 -0.379143 -vn -0.946638 -0.198907 -0.253600 -vn -0.970776 0.085464 -0.224254 -vn -0.970776 0.085464 -0.224254 -vn -0.865986 0.007573 -0.500011 -vn -0.915190 -0.136671 -0.379143 -vn -0.982121 -0.136787 -0.129332 -vn -0.974045 -0.216081 0.067421 -vn -0.998818 0.048476 0.003588 -vn -0.998818 0.048476 0.003588 -vn -0.970776 0.085464 -0.224254 -vn -0.982121 -0.136787 -0.129332 -vn -0.820199 -0.548350 -0.163050 -vn -0.773684 -0.625316 -0.101943 -vn -0.982121 -0.136787 -0.129332 -vn -0.820199 -0.548350 -0.163050 -vn -0.982121 -0.136787 -0.129332 -vn -0.946638 -0.198907 -0.253600 -vn -0.834536 -0.548214 -0.054865 -vn -0.774567 -0.626221 0.088845 -vn -0.974045 -0.216081 0.067421 -vn -0.974045 -0.216081 0.067421 -vn -0.982121 -0.136787 -0.129332 -vn -0.834536 -0.548214 -0.054865 -vn -0.773684 -0.625316 -0.101943 -vn -0.197953 -0.979864 -0.026106 -vn -0.199250 -0.979861 -0.013125 -vn -0.834536 -0.548214 -0.054865 -vn -0.199250 -0.979861 -0.013125 -vn -0.195626 -0.976106 0.094593 -vn -0.199250 -0.979861 -0.013125 -vn 0.079824 -0.996795 0.005260 -vn -0.059975 -0.994232 0.088919 -vn -0.197953 -0.979864 -0.026106 -vn 0.079314 -0.996795 0.010461 -vn 0.079824 -0.996795 0.005260 -vn -0.753817 -0.625309 -0.201863 -vn -0.192889 -0.979859 -0.051676 -vn -0.195829 -0.979864 -0.038953 -vn -0.820199 -0.548350 -0.163050 -vn -0.195829 -0.979864 -0.038953 -vn -0.197953 -0.979864 -0.026106 -vn -0.195829 -0.979864 -0.038953 -vn 0.078460 -0.996795 0.015609 -vn 0.079314 -0.996795 0.010461 -vn -0.192889 -0.979859 -0.051676 -vn 0.077272 -0.996795 0.020703 -vn 0.078460 -0.996795 0.015609 -vn -0.749973 -0.548375 -0.369898 -vn -0.720908 -0.625314 -0.298787 -vn -0.915190 -0.136671 -0.379143 -vn -0.915190 -0.136671 -0.379143 -vn -0.848748 -0.198912 -0.489960 -vn -0.749973 -0.548375 -0.369898 -vn -0.792045 -0.548040 -0.268918 -vn -0.753817 -0.625309 -0.201863 -vn -0.946638 -0.198907 -0.253600 -vn -0.946638 -0.198907 -0.253600 -vn -0.915190 -0.136671 -0.379143 -vn -0.792045 -0.548040 -0.268918 -vn -0.720908 -0.625314 -0.298787 -vn -0.184454 -0.979861 -0.076474 -vn -0.189096 -0.979856 -0.064228 -vn -0.792045 -0.548040 -0.268918 -vn -0.189096 -0.979856 -0.064228 -vn -0.192889 -0.979859 -0.051676 -vn -0.189096 -0.979856 -0.064228 -vn 0.075746 -0.996795 0.025730 -vn 0.077272 -0.996795 0.020703 -vn -0.184454 -0.979861 -0.076474 -vn 0.073898 -0.996795 0.030640 -vn 0.075746 -0.996795 0.025730 -vn -0.675878 -0.625313 -0.390093 -vn -0.172924 -0.979863 -0.099831 -vn -0.179057 -0.979865 -0.088341 -vn -0.749973 -0.548375 -0.369898 -vn -0.179057 -0.979865 -0.088341 -vn -0.184454 -0.979861 -0.076474 -vn -0.179057 -0.979865 -0.088341 -vn 0.071742 -0.996795 0.035397 -vn 0.073898 -0.996795 0.030640 -vn -0.172924 -0.979863 -0.099831 -vn 0.069281 -0.996795 0.039999 -vn 0.071742 -0.996795 0.035397 -vn -0.559013 0.035015 -0.828420 -vn -0.489963 -0.198913 -0.848746 -vn -0.603081 -0.136554 -0.785905 -vn -0.603081 -0.136554 -0.785905 -vn -0.679581 0.085468 -0.728605 -vn -0.559013 0.035015 -0.828420 -vn -0.785908 -0.136554 -0.603077 -vn -0.848748 -0.198912 -0.489960 -vn -0.865986 0.007573 -0.500011 -vn -0.865986 0.007573 -0.500011 -vn -0.679581 0.085468 -0.728605 -vn -0.785908 -0.136554 -0.603077 -vn -0.628648 -0.548296 -0.551520 -vn -0.619062 -0.625306 -0.475137 -vn -0.785908 -0.136554 -0.603077 -vn -0.785908 -0.136554 -0.603077 -vn -0.692977 -0.198918 -0.692975 -vn -0.628648 -0.548296 -0.551520 -vn -0.695502 -0.548117 -0.464591 -vn -0.675878 -0.625313 -0.390093 -vn -0.848748 -0.198912 -0.489960 -vn -0.695502 -0.548117 -0.464591 -vn -0.848748 -0.198912 -0.489960 -vn -0.785908 -0.136554 -0.603077 -vn -0.619062 -0.625306 -0.475137 -vn -0.158405 -0.979857 -0.121607 -vn -0.166042 -0.979858 -0.110944 -vn -0.695502 -0.548117 -0.464591 -vn -0.166042 -0.979858 -0.110944 -vn -0.172924 -0.979863 -0.099831 -vn -0.166042 -0.979858 -0.110944 -vn 0.066515 -0.996795 0.044445 -vn 0.069281 -0.996795 0.039999 -vn -0.158405 -0.979857 -0.121607 -vn 0.063454 -0.996795 0.048715 -vn 0.066515 -0.996795 0.044445 -vn -0.551796 -0.625317 -0.551816 -vn -0.141165 -0.979865 -0.141202 -vn -0.150082 -0.979862 -0.131702 -vn -0.628648 -0.548296 -0.551520 -vn -0.150082 -0.979862 -0.131702 -vn -0.158405 -0.979857 -0.121607 -vn -0.150082 -0.979862 -0.131702 -vn 0.060129 -0.996795 0.052767 -vn 0.063454 -0.996795 0.048715 -vn -0.141165 -0.979865 -0.141202 -vn 0.056560 -0.996795 0.056577 -vn 0.060129 -0.996795 0.052767 -vn -0.464580 -0.548113 -0.695513 -vn -0.475115 -0.625305 -0.619080 -vn -0.603081 -0.136554 -0.785905 -vn -0.603081 -0.136554 -0.785905 -vn -0.489963 -0.198913 -0.848746 -vn -0.464580 -0.548113 -0.695513 -vn -0.551508 -0.548294 -0.628659 -vn -0.551796 -0.625317 -0.551816 -vn -0.692977 -0.198918 -0.692975 -vn -0.551508 -0.548294 -0.628659 -vn -0.692977 -0.198918 -0.692975 -vn -0.603081 -0.136554 -0.785905 -vn -0.475115 -0.625305 -0.619080 -vn -0.121566 -0.979857 -0.158438 -vn -0.131662 -0.979863 -0.150115 -vn -0.551508 -0.548294 -0.628659 -vn -0.131662 -0.979863 -0.150115 -vn -0.141165 -0.979865 -0.141202 -vn -0.131662 -0.979863 -0.150115 -vn 0.052748 -0.996795 0.060144 -vn 0.056560 -0.996795 0.056577 -vn -0.121566 -0.979857 -0.158438 -vn 0.048696 -0.996795 0.063468 -vn 0.052748 -0.996795 0.060144 -vn -0.390067 -0.625315 -0.675892 -vn -0.099785 -0.979863 -0.172949 -vn -0.110900 -0.979858 -0.166071 -vn -0.464580 -0.548113 -0.695513 -vn -0.110900 -0.979858 -0.166071 -vn -0.121566 -0.979857 -0.158438 -vn -0.110900 -0.979858 -0.166071 -vn 0.044424 -0.996795 0.066528 -vn 0.048696 -0.996795 0.063468 -vn -0.099785 -0.979863 -0.172949 -vn 0.039978 -0.996795 0.069293 -vn 0.044424 -0.996795 0.066528 -vn -0.499945 0.102956 -0.859916 -vn -0.500192 0.089907 -0.861234 -vn -0.863780 0.089908 -0.495782 -vn -0.862907 0.102956 -0.494765 -vn -0.863780 0.089908 -0.495782 -vn -0.995947 0.089909 0.002546 -vn -0.863780 0.089908 -0.495782 -vn -0.864783 0.062737 -0.498211 -vn -0.998889 0.047128 0.000794 -vn -0.500192 0.089907 -0.861234 -vn -0.522059 0.054243 -0.851183 -vn -0.864783 0.062737 -0.498211 -vn -0.861619 0.119288 -0.493338 -vn -0.862116 0.112906 -0.493972 -vn -0.993600 0.112908 0.003282 -vn -0.862116 0.112906 -0.493972 -vn -0.862907 0.102956 -0.494765 -vn -0.994681 0.102958 0.002990 -vn -0.499657 0.112906 -0.858834 -vn -0.499945 0.102956 -0.859916 -vn -0.862907 0.102956 -0.494765 -vn 0.863839 0.062737 -0.499846 -vn 0.998889 0.047128 -0.000794 -vn 0.998507 0.054619 0.000000 -vn 0.863839 0.062737 -0.499846 -vn 0.998507 0.054619 0.000000 -vn 0.970776 0.085464 -0.224254 -vn 0.520588 0.054246 -0.852083 -vn 0.559013 0.035015 -0.828420 -vn 0.224256 0.085466 -0.970775 -vn 0.224256 0.085466 -0.970775 -vn -0.000000 0.054620 -0.998507 -vn 0.520588 0.054246 -0.852083 -vn -0.224256 0.085466 -0.970775 -vn -0.559013 0.035015 -0.828420 -vn -0.522059 0.054243 -0.851183 -vn -0.522059 0.054243 -0.851183 -vn -0.000000 0.054620 -0.998507 -vn -0.224256 0.085466 -0.970775 -vn -0.129333 -0.136787 -0.982121 -vn -0.253603 -0.198906 -0.946637 -vn -0.224256 0.085466 -0.970775 -vn -0.129333 -0.136787 -0.982121 -vn -0.224256 0.085466 -0.970775 -vn -0.000000 0.054620 -0.998507 -vn -0.379146 -0.136670 -0.915188 -vn -0.489963 -0.198913 -0.848746 -vn -0.559013 0.035015 -0.828420 -vn -0.379146 -0.136670 -0.915188 -vn -0.559013 0.035015 -0.828420 -vn -0.224256 0.085466 -0.970775 -vn -0.268901 -0.548039 -0.792052 -vn -0.298761 -0.625313 -0.720920 -vn -0.379146 -0.136670 -0.915188 -vn -0.268901 -0.548039 -0.792052 -vn -0.379146 -0.136670 -0.915188 -vn -0.253603 -0.198906 -0.946637 -vn -0.369884 -0.548374 -0.749982 -vn -0.390067 -0.625315 -0.675892 -vn -0.489963 -0.198913 -0.848746 -vn -0.369884 -0.548374 -0.749982 -vn -0.489963 -0.198913 -0.848746 -vn -0.379146 -0.136670 -0.915188 -vn -0.298761 -0.625313 -0.720920 -vn -0.076426 -0.979861 -0.184474 -vn -0.088294 -0.979865 -0.179080 -vn -0.369884 -0.548374 -0.749982 -vn -0.088294 -0.979865 -0.179080 -vn -0.099785 -0.979863 -0.172949 -vn -0.088294 -0.979865 -0.179080 -vn 0.035375 -0.996795 0.071753 -vn 0.039978 -0.996795 0.069293 -vn -0.076426 -0.979861 -0.184474 -vn 0.030617 -0.996795 0.073907 -vn 0.035375 -0.996795 0.071753 -vn -0.201834 -0.625309 -0.753825 -vn -0.051625 -0.979859 -0.192902 -vn -0.064178 -0.979856 -0.189113 -vn -0.268901 -0.548039 -0.792052 -vn -0.064178 -0.979856 -0.189113 -vn -0.076426 -0.979861 -0.184474 -vn -0.064178 -0.979856 -0.189113 -vn 0.025707 -0.996795 0.075754 -vn 0.030617 -0.996795 0.073907 -vn -0.051625 -0.979859 -0.192902 -vn 0.020680 -0.996795 0.077279 -vn 0.025707 -0.996795 0.075754 -vn -0.054845 -0.548214 -0.834538 -vn -0.101911 -0.625316 -0.773688 -vn -0.129333 -0.136787 -0.982121 -vn -0.054845 -0.548214 -0.834538 -vn -0.129333 -0.136787 -0.982121 -vn 0.000000 -0.198908 -0.980018 -vn -0.163032 -0.548348 -0.820204 -vn -0.201834 -0.625309 -0.753825 -vn -0.253603 -0.198906 -0.946637 -vn -0.253603 -0.198906 -0.946637 -vn -0.129333 -0.136787 -0.982121 -vn -0.163032 -0.548348 -0.820204 -vn -0.101911 -0.625316 -0.773688 -vn -0.026053 -0.979864 -0.197959 -vn -0.038902 -0.979864 -0.195841 -vn -0.163032 -0.548348 -0.820204 -vn -0.038902 -0.979864 -0.195841 -vn -0.051625 -0.979859 -0.192902 -vn -0.038902 -0.979864 -0.195841 -vn 0.015585 -0.996795 0.078466 -vn 0.020680 -0.996795 0.077279 -vn -0.026053 -0.979864 -0.197959 -vn 0.010437 -0.996795 0.079315 -vn 0.015585 -0.996795 0.078466 -vn 0.000016 -0.625302 -0.780383 -vn 0.000027 -0.979855 -0.199708 -vn -0.013072 -0.979860 -0.199255 -vn -0.054845 -0.548214 -0.834538 -vn -0.013072 -0.979860 -0.199255 -vn -0.026053 -0.979864 -0.197959 -vn -0.013072 -0.979860 -0.199255 -vn 0.005235 -0.996795 0.079826 -vn 0.010437 -0.996795 0.079315 -vn 0.000027 -0.979855 -0.199708 -vn -0.000012 -0.996795 0.079997 -vn 0.005235 -0.996795 0.079826 -vn 0.379146 -0.136670 -0.915188 -vn 0.253603 -0.198906 -0.946637 -vn 0.224256 0.085466 -0.970775 -vn 0.224256 0.085466 -0.970775 -vn 0.559013 0.035015 -0.828420 -vn 0.379146 -0.136670 -0.915188 -vn 0.129333 -0.136787 -0.982121 -vn 0.000000 -0.198908 -0.980018 -vn -0.000000 0.054620 -0.998507 -vn -0.000000 0.054620 -0.998507 -vn 0.224256 0.085466 -0.970775 -vn 0.129333 -0.136787 -0.982121 -vn 0.163052 -0.548348 -0.820200 -vn 0.101942 -0.625316 -0.773684 -vn 0.129333 -0.136787 -0.982121 -vn 0.163052 -0.548348 -0.820200 -vn 0.129333 -0.136787 -0.982121 -vn 0.253603 -0.198906 -0.946637 -vn 0.054866 -0.548214 -0.834537 -vn 0.000016 -0.625302 -0.780383 -vn 0.000000 -0.198908 -0.980018 -vn 0.000000 -0.198908 -0.980018 -vn 0.129333 -0.136787 -0.982121 -vn 0.054866 -0.548214 -0.834537 -vn 0.101942 -0.625316 -0.773684 -vn 0.026105 -0.979864 -0.197952 -vn 0.013125 -0.979860 -0.199252 -vn 0.054866 -0.548214 -0.834537 -vn 0.013125 -0.979860 -0.199252 -vn 0.000027 -0.979855 -0.199708 -vn 0.013125 -0.979860 -0.199252 -vn -0.005260 -0.996795 0.079825 -vn -0.000012 -0.996795 0.079997 -vn 0.026105 -0.979864 -0.197952 -vn -0.010461 -0.996795 0.079312 -vn -0.005260 -0.996795 0.079825 -vn 0.201864 -0.625309 -0.753817 -vn 0.051676 -0.979859 -0.192887 -vn 0.038954 -0.979864 -0.195830 -vn 0.163052 -0.548348 -0.820200 -vn 0.038954 -0.979864 -0.195830 -vn 0.026105 -0.979864 -0.197952 -vn 0.038954 -0.979864 -0.195830 -vn -0.015609 -0.996795 0.078461 -vn -0.010461 -0.996795 0.079312 -vn 0.051676 -0.979859 -0.192887 -vn -0.020704 -0.996795 0.077272 -vn -0.015609 -0.996795 0.078461 -vn 0.369902 -0.548374 -0.749972 -vn 0.298790 -0.625312 -0.720908 -vn 0.379146 -0.136670 -0.915188 -vn 0.379146 -0.136670 -0.915188 -vn 0.489963 -0.198913 -0.848746 -vn 0.369902 -0.548374 -0.749972 -vn 0.268920 -0.548039 -0.792045 -vn 0.201864 -0.625309 -0.753817 -vn 0.253603 -0.198906 -0.946637 -vn 0.253603 -0.198906 -0.946637 -vn 0.379146 -0.136670 -0.915188 -vn 0.268920 -0.548039 -0.792045 -vn 0.298790 -0.625312 -0.720908 -vn 0.076475 -0.979861 -0.184454 -vn 0.064229 -0.979856 -0.189096 -vn 0.268920 -0.548039 -0.792045 -vn 0.064229 -0.979856 -0.189096 -vn 0.051676 -0.979859 -0.192887 -vn 0.064229 -0.979856 -0.189096 -vn -0.025730 -0.996795 0.075746 -vn -0.020704 -0.996795 0.077272 -vn 0.076475 -0.979861 -0.184454 -vn -0.030640 -0.996795 0.073898 -vn -0.025730 -0.996795 0.075746 -vn 0.390094 -0.625314 -0.675876 -vn 0.099830 -0.979863 -0.172922 -vn 0.088341 -0.979865 -0.179057 -vn 0.369902 -0.548374 -0.749972 -vn 0.088341 -0.979865 -0.179057 -vn 0.076475 -0.979861 -0.184454 -vn 0.088341 -0.979865 -0.179057 -vn -0.035397 -0.996795 0.071742 -vn -0.030640 -0.996795 0.073898 -vn 0.099830 -0.979863 -0.172922 -vn -0.039999 -0.996795 0.069281 -vn -0.035397 -0.996795 0.071742 -vn 0.863839 0.062737 -0.499846 -vn 0.865986 0.007573 -0.500011 -vn 0.679581 0.085468 -0.728605 -vn 0.679581 0.085468 -0.728605 -vn 0.559013 0.035015 -0.828420 -vn 0.863839 0.062737 -0.499846 -vn 0.785908 -0.136554 -0.603077 -vn 0.692977 -0.198918 -0.692975 -vn 0.679581 0.085468 -0.728605 -vn 0.785908 -0.136554 -0.603077 -vn 0.679581 0.085468 -0.728605 -vn 0.865986 0.007573 -0.500011 -vn 0.603081 -0.136554 -0.785905 -vn 0.489963 -0.198913 -0.848746 -vn 0.559013 0.035015 -0.828420 -vn 0.559013 0.035015 -0.828420 -vn 0.679581 0.085468 -0.728605 -vn 0.603081 -0.136554 -0.785905 -vn 0.551523 -0.548295 -0.628645 -vn 0.475140 -0.625305 -0.619061 -vn 0.603081 -0.136554 -0.785905 -vn 0.603081 -0.136554 -0.785905 -vn 0.692977 -0.198918 -0.692975 -vn 0.551523 -0.548295 -0.628645 -vn 0.464597 -0.548113 -0.695501 -vn 0.390094 -0.625314 -0.675876 -vn 0.489963 -0.198913 -0.848746 -vn 0.464597 -0.548113 -0.695501 -vn 0.489963 -0.198913 -0.848746 -vn 0.603081 -0.136554 -0.785905 -vn 0.475140 -0.625305 -0.619061 -vn 0.121608 -0.979857 -0.158406 -vn 0.110944 -0.979858 -0.166042 -vn 0.464597 -0.548113 -0.695501 -vn 0.110944 -0.979858 -0.166042 -vn 0.099830 -0.979863 -0.172922 -vn 0.110944 -0.979858 -0.166042 -vn -0.044445 -0.996795 0.066514 -vn -0.039999 -0.996795 0.069281 -vn 0.121608 -0.979857 -0.158406 -vn -0.048715 -0.996795 0.063453 -vn -0.044445 -0.996795 0.066514 -vn 0.551819 -0.625315 -0.551794 -vn 0.141203 -0.979865 -0.141164 -vn 0.131702 -0.979863 -0.150080 -vn 0.551523 -0.548295 -0.628645 -vn 0.131702 -0.979863 -0.150080 -vn 0.121608 -0.979857 -0.158406 -vn 0.131702 -0.979863 -0.150080 -vn -0.052767 -0.996795 0.060128 -vn -0.048715 -0.996795 0.063453 -vn 0.141203 -0.979865 -0.141164 -vn -0.056577 -0.996795 0.056559 -vn -0.052767 -0.996795 0.060128 -vn 0.695513 -0.548117 -0.464574 -vn 0.619082 -0.625304 -0.475112 -vn 0.785908 -0.136554 -0.603077 -vn 0.785908 -0.136554 -0.603077 -vn 0.848748 -0.198912 -0.489960 -vn 0.695513 -0.548117 -0.464574 -vn 0.628661 -0.548296 -0.551504 -vn 0.551819 -0.625315 -0.551794 -vn 0.692977 -0.198918 -0.692975 -vn 0.628661 -0.548296 -0.551504 -vn 0.692977 -0.198918 -0.692975 -vn 0.785908 -0.136554 -0.603077 -vn 0.619082 -0.625304 -0.475112 -vn 0.158439 -0.979857 -0.121565 -vn 0.150116 -0.979863 -0.131661 -vn 0.628661 -0.548296 -0.551504 -vn 0.150116 -0.979863 -0.131661 -vn 0.141203 -0.979865 -0.141164 -vn 0.150116 -0.979863 -0.131661 -vn -0.060145 -0.996795 0.052748 -vn -0.056577 -0.996795 0.056559 -vn 0.158439 -0.979857 -0.121565 -vn -0.063469 -0.996795 0.048696 -vn -0.060145 -0.996795 0.052748 -vn 0.675893 -0.625315 -0.390065 -vn 0.172949 -0.979863 -0.099784 -vn 0.166073 -0.979858 -0.110900 -vn 0.695513 -0.548117 -0.464574 -vn 0.166073 -0.979858 -0.110900 -vn 0.158439 -0.979857 -0.121565 -vn 0.166073 -0.979858 -0.110900 -vn -0.066529 -0.996795 0.044425 -vn -0.063469 -0.996795 0.048696 -vn 0.172949 -0.979863 -0.099784 -vn -0.069293 -0.996795 0.039977 -vn -0.066529 -0.996795 0.044425 -vn 0.998507 0.054619 0.000000 -vn 0.980018 -0.198907 0.000000 -vn 0.982121 -0.136787 -0.129332 -vn 0.982121 -0.136787 -0.129332 -vn 0.970776 0.085464 -0.224254 -vn 0.998507 0.054619 0.000000 -vn 0.915190 -0.136671 -0.379143 -vn 0.848748 -0.198912 -0.489960 -vn 0.865986 0.007573 -0.500011 -vn 0.915190 -0.136671 -0.379143 -vn 0.865986 0.007573 -0.500011 -vn 0.970776 0.085464 -0.224254 -vn 0.792052 -0.548040 -0.268898 -vn 0.720921 -0.625312 -0.298759 -vn 0.915190 -0.136671 -0.379143 -vn 0.792052 -0.548040 -0.268898 -vn 0.915190 -0.136671 -0.379143 -vn 0.946638 -0.198907 -0.253600 -vn 0.749983 -0.548375 -0.369880 -vn 0.675893 -0.625315 -0.390065 -vn 0.848748 -0.198912 -0.489960 -vn 0.749983 -0.548375 -0.369880 -vn 0.848748 -0.198912 -0.489960 -vn 0.915190 -0.136671 -0.379143 -vn 0.720921 -0.625312 -0.298759 -vn 0.184475 -0.979861 -0.076425 -vn 0.179081 -0.979865 -0.088293 -vn 0.749983 -0.548375 -0.369880 -vn 0.179081 -0.979865 -0.088293 -vn 0.172949 -0.979863 -0.099784 -vn 0.179081 -0.979865 -0.088293 -vn -0.071753 -0.996795 0.035375 -vn -0.069293 -0.996795 0.039977 -vn 0.184475 -0.979861 -0.076425 -vn -0.073908 -0.996795 0.030617 -vn -0.071753 -0.996795 0.035375 -vn 0.753824 -0.625311 -0.201832 -vn 0.192902 -0.979859 -0.051624 -vn 0.189113 -0.979856 -0.064178 -vn 0.792052 -0.548040 -0.268898 -vn 0.189113 -0.979856 -0.064178 -vn 0.184475 -0.979861 -0.076425 -vn 0.189113 -0.979856 -0.064178 -vn -0.075754 -0.996795 0.025706 -vn -0.073908 -0.996795 0.030617 -vn 0.192902 -0.979859 -0.051624 -vn -0.077279 -0.996795 0.020680 -vn -0.075754 -0.996795 0.025706 -vn 0.980018 -0.198907 0.000000 -vn 0.780383 -0.625302 0.000016 -vn 0.834538 -0.548214 -0.054844 -vn 0.834538 -0.548214 -0.054844 -vn 0.982121 -0.136787 -0.129332 -vn 0.980018 -0.198907 0.000000 -vn 0.820204 -0.548349 -0.163030 -vn 0.753824 -0.625311 -0.201832 -vn 0.946638 -0.198907 -0.253600 -vn 0.946638 -0.198907 -0.253600 -vn 0.982121 -0.136787 -0.129332 -vn 0.820204 -0.548349 -0.163030 -vn 0.773688 -0.625316 -0.101912 -vn 0.197959 -0.979864 -0.026053 -vn 0.195842 -0.979864 -0.038902 -vn 0.820204 -0.548349 -0.163030 -vn 0.195842 -0.979864 -0.038902 -vn 0.192902 -0.979859 -0.051624 -vn 0.195842 -0.979864 -0.038902 -vn -0.078466 -0.996795 0.015585 -vn -0.077279 -0.996795 0.020680 -vn 0.197959 -0.979864 -0.026053 -vn -0.079316 -0.996795 0.010437 -vn -0.078466 -0.996795 0.015585 -vn 0.780383 -0.625302 0.000016 -vn 0.199709 -0.979855 0.000026 -vn 0.199256 -0.979860 -0.013072 -vn 0.834538 -0.548214 -0.054844 -vn 0.199256 -0.979860 -0.013072 -vn 0.197959 -0.979864 -0.026053 -vn 0.199256 -0.979860 -0.013072 -vn -0.079827 -0.996795 0.005235 -vn -0.079316 -0.996795 0.010437 -vn 0.199709 -0.979855 0.000026 -vn -0.079997 -0.996795 -0.000012 -vn -0.079827 -0.996795 0.005235 -vn 0.493340 0.119288 -0.861618 -vn 0.493974 0.112906 -0.862115 -vn -0.003282 0.112908 -0.993600 -vn 0.494767 0.102956 -0.862905 -vn 0.495785 0.089908 -0.863779 -vn -0.002546 0.089909 -0.995947 -vn -0.002990 0.102958 -0.994681 -vn -0.002546 0.089909 -0.995947 -vn -0.500192 0.089907 -0.861234 -vn -0.002546 0.089909 -0.995947 -vn -0.000794 0.047128 -0.998889 -vn -0.522059 0.054243 -0.851183 -vn 0.495785 0.089908 -0.863779 -vn 0.520588 0.054246 -0.852083 -vn -0.000794 0.047128 -0.998889 -vn -0.003582 0.119290 -0.992853 -vn -0.003282 0.112908 -0.993600 -vn -0.499657 0.112906 -0.858834 -vn -0.003282 0.112908 -0.993600 -vn -0.002990 0.102958 -0.994681 -vn -0.499945 0.102956 -0.859916 -vn 0.493974 0.112906 -0.862115 -vn 0.494767 0.102956 -0.862905 -vn -0.002990 0.102958 -0.994681 -vn 0.994681 0.102958 -0.002990 -vn 0.995947 0.089909 -0.002546 -vn 0.861235 0.089907 -0.500190 -vn 0.859917 0.102956 -0.499943 -vn 0.861235 0.089907 -0.500190 -vn 0.495785 0.089908 -0.863779 -vn 0.861235 0.089907 -0.500190 -vn 0.863839 0.062737 -0.499846 -vn 0.520588 0.054246 -0.852083 -vn 0.995947 0.089909 -0.002546 -vn 0.998889 0.047128 -0.000794 -vn 0.863839 0.062737 -0.499846 -vn 0.858038 0.119287 -0.499541 -vn 0.858835 0.112906 -0.499655 -vn 0.493974 0.112906 -0.862115 -vn 0.858835 0.112906 -0.499655 -vn 0.859917 0.102956 -0.499943 -vn 0.494767 0.102956 -0.862905 -vn 0.993600 0.112908 -0.003282 -vn 0.994681 0.102958 -0.002990 -vn 0.859917 0.102956 -0.499943 -vn -0.499499 0.138592 -0.855157 -vn -0.499269 0.137445 -0.855476 -vn -0.860102 0.137445 -0.491258 -vn -0.499366 0.128646 -0.856787 -vn -0.499410 0.124651 -0.857352 -vn -0.861162 0.124651 -0.492811 -vn -0.860841 0.128646 -0.492344 -vn -0.861162 0.124651 -0.492811 -vn -0.992193 0.124653 0.003810 -vn -0.861162 0.124651 -0.492811 -vn -0.861619 0.119288 -0.493338 -vn -0.992853 0.119290 0.003582 -vn -0.499410 0.124651 -0.857352 -vn -0.499543 0.119288 -0.858037 -vn -0.861619 0.119288 -0.493338 -vn -0.499299 0.134937 -0.855858 -vn -0.499292 0.132157 -0.856295 -vn -0.860532 0.132157 -0.491955 -vn -0.860318 0.134936 -0.491574 -vn -0.860532 0.132157 -0.491955 -vn -0.991220 0.132159 0.004236 -vn -0.860532 0.132157 -0.491955 -vn -0.860841 0.128646 -0.492344 -vn -0.991682 0.128649 0.004054 -vn -0.499292 0.132157 -0.856295 -vn -0.499366 0.128646 -0.856787 -vn -0.860841 0.128646 -0.492344 -vn -0.860140 0.138592 -0.490867 -vn -0.860102 0.137445 -0.491258 -vn -0.990498 0.137448 0.004625 -vn -0.860102 0.137445 -0.491258 -vn -0.860318 0.134936 -0.491574 -vn -0.990844 0.134939 0.004460 -vn -0.499269 0.137445 -0.855476 -vn -0.499299 0.134937 -0.855858 -vn -0.860318 0.134936 -0.491574 -vn 0.991682 0.128649 -0.004054 -vn 0.992193 0.124653 -0.003810 -vn 0.857353 0.124650 -0.499408 -vn 0.492346 0.128646 -0.860840 -vn 0.492814 0.124651 -0.861160 -vn -0.003810 0.124653 -0.992193 -vn -0.004054 0.128649 -0.991682 -vn -0.003810 0.124653 -0.992193 -vn -0.499410 0.124651 -0.857352 -vn -0.003810 0.124653 -0.992193 -vn -0.003582 0.119290 -0.992853 -vn -0.499543 0.119288 -0.858037 -vn 0.492814 0.124651 -0.861160 -vn 0.493340 0.119288 -0.861618 -vn -0.003582 0.119290 -0.992853 -vn 0.856788 0.128646 -0.499364 -vn 0.857353 0.124650 -0.499408 -vn 0.492814 0.124651 -0.861160 -vn 0.857353 0.124650 -0.499408 -vn 0.858038 0.119287 -0.499541 -vn 0.493340 0.119288 -0.861618 -vn 0.992193 0.124653 -0.003810 -vn 0.992853 0.119290 -0.003582 -vn 0.858038 0.119287 -0.499541 -vn 0.490869 0.138592 -0.860139 -vn 0.491260 0.137445 -0.860100 -vn -0.004625 0.137448 -0.990498 -vn 0.491576 0.134936 -0.860317 -vn 0.491957 0.132157 -0.860530 -vn -0.004236 0.132159 -0.991220 -vn -0.004460 0.134939 -0.990844 -vn -0.004236 0.132159 -0.991220 -vn -0.499292 0.132157 -0.856295 -vn -0.004236 0.132159 -0.991220 -vn -0.004054 0.128649 -0.991682 -vn -0.499366 0.128646 -0.856787 -vn 0.491957 0.132157 -0.860530 -vn 0.492346 0.128646 -0.860840 -vn -0.004054 0.128649 -0.991682 -vn -0.004983 0.138595 -0.990337 -vn -0.004625 0.137448 -0.990498 -vn -0.499269 0.137445 -0.855476 -vn -0.004625 0.137448 -0.990498 -vn -0.004460 0.134939 -0.990844 -vn -0.499299 0.134937 -0.855858 -vn 0.491260 0.137445 -0.860100 -vn 0.491576 0.134936 -0.860317 -vn -0.004460 0.134939 -0.990844 -vn 0.990844 0.134939 -0.004460 -vn 0.991220 0.132159 -0.004236 -vn 0.856296 0.132157 -0.499291 -vn 0.855859 0.134936 -0.499297 -vn 0.856296 0.132157 -0.499291 -vn 0.491957 0.132157 -0.860530 -vn 0.856296 0.132157 -0.499291 -vn 0.856788 0.128646 -0.499364 -vn 0.492346 0.128646 -0.860840 -vn 0.991220 0.132159 -0.004236 -vn 0.991682 0.128649 -0.004054 -vn 0.856788 0.128646 -0.499364 -vn 0.855158 0.138592 -0.499497 -vn 0.855477 0.137445 -0.499267 -vn 0.491260 0.137445 -0.860100 -vn 0.855477 0.137445 -0.499267 -vn 0.855859 0.134936 -0.499297 -vn 0.491576 0.134936 -0.860317 -vn 0.990498 0.137448 -0.004625 -vn 0.990844 0.134939 -0.004460 -vn 0.855859 0.134936 -0.499297 -vn -0.992853 0.119290 0.003582 -vn -0.993600 0.112908 0.003282 -vn -0.858835 0.112906 0.499655 -vn 0.499543 0.119288 0.858037 -vn 0.499657 0.112906 0.858834 -vn 0.862116 0.112906 0.493972 -vn 0.679581 0.085468 0.728605 -vn 0.865986 0.007573 0.500011 -vn 0.864783 0.062737 0.498211 -vn 0.864783 0.062737 0.498211 -vn 0.559013 0.035015 0.828420 -vn 0.679581 0.085468 0.728605 -vn 0.864783 0.062737 0.498211 -vn 0.865986 0.007573 0.500011 -vn 0.970776 0.085464 0.224254 -vn 0.970776 0.085464 0.224254 -vn 0.998507 0.054619 0.000000 -vn 0.864783 0.062737 0.498211 -vn 0.915190 -0.136671 0.379143 -vn 0.946638 -0.198907 0.253600 -vn 0.970776 0.085464 0.224254 -vn 0.970776 0.085464 0.224254 -vn 0.865986 0.007573 0.500011 -vn 0.915190 -0.136671 0.379143 -vn 0.982121 -0.136787 0.129332 -vn 0.980018 -0.198907 0.000000 -vn 0.998507 0.054619 0.000000 -vn 0.998507 0.054619 0.000000 -vn 0.970776 0.085464 0.224254 -vn 0.982121 -0.136787 0.129332 -vn 0.820199 -0.548350 0.163050 -vn 0.773684 -0.625316 0.101943 -vn 0.982121 -0.136787 0.129332 -vn 0.820199 -0.548350 0.163050 -vn 0.982121 -0.136787 0.129332 -vn 0.946638 -0.198907 0.253600 -vn 0.834536 -0.548215 0.054865 -vn 0.780383 -0.625302 0.000016 -vn 0.980018 -0.198907 0.000000 -vn 0.980018 -0.198907 0.000000 -vn 0.982121 -0.136787 0.129332 -vn 0.834536 -0.548215 0.054865 -vn 0.773684 -0.625316 0.101943 -vn 0.197953 -0.979864 0.026106 -vn 0.199250 -0.979861 0.013125 -vn 0.834536 -0.548215 0.054865 -vn 0.199250 -0.979861 0.013125 -vn 0.199709 -0.979855 0.000026 -vn 0.199250 -0.979861 0.013125 -vn -0.079824 -0.996795 -0.005260 -vn -0.079997 -0.996795 -0.000012 -vn 0.197953 -0.979864 0.026106 -vn -0.079314 -0.996795 -0.010461 -vn -0.079824 -0.996795 -0.005260 -vn 0.753817 -0.625309 0.201863 -vn 0.192889 -0.979859 0.051676 -vn 0.195829 -0.979864 0.038953 -vn 0.820199 -0.548350 0.163050 -vn 0.195829 -0.979864 0.038953 -vn 0.197953 -0.979864 0.026106 -vn 0.195829 -0.979864 0.038953 -vn -0.078460 -0.996795 -0.015609 -vn -0.079314 -0.996795 -0.010461 -vn 0.192889 -0.979859 0.051676 -vn -0.077272 -0.996795 -0.020703 -vn -0.078460 -0.996795 -0.015609 -vn 0.749973 -0.548375 0.369898 -vn 0.720908 -0.625314 0.298787 -vn 0.915190 -0.136671 0.379143 -vn 0.915190 -0.136671 0.379143 -vn 0.848748 -0.198912 0.489960 -vn 0.749973 -0.548375 0.369898 -vn 0.792045 -0.548040 0.268918 -vn 0.753817 -0.625309 0.201863 -vn 0.946638 -0.198907 0.253600 -vn 0.946638 -0.198907 0.253600 -vn 0.915190 -0.136671 0.379143 -vn 0.792045 -0.548040 0.268918 -vn 0.720908 -0.625314 0.298787 -vn 0.184454 -0.979861 0.076474 -vn 0.189096 -0.979856 0.064228 -vn 0.792045 -0.548040 0.268918 -vn 0.189096 -0.979856 0.064228 -vn 0.192889 -0.979859 0.051676 -vn 0.189096 -0.979856 0.064228 -vn -0.075746 -0.996795 -0.025730 -vn -0.077272 -0.996795 -0.020703 -vn 0.184454 -0.979861 0.076474 -vn -0.073898 -0.996795 -0.030640 -vn -0.075746 -0.996795 -0.025730 -vn 0.675878 -0.625313 0.390093 -vn 0.172924 -0.979863 0.099831 -vn 0.179057 -0.979865 0.088341 -vn 0.749973 -0.548375 0.369898 -vn 0.179057 -0.979865 0.088341 -vn 0.184454 -0.979861 0.076474 -vn 0.179057 -0.979865 0.088341 -vn -0.071742 -0.996795 -0.035397 -vn -0.073898 -0.996795 -0.030640 -vn 0.172924 -0.979863 0.099831 -vn -0.069281 -0.996795 -0.039999 -vn -0.071742 -0.996795 -0.035397 -vn 0.603081 -0.136554 0.785905 -vn 0.692977 -0.198918 0.692975 -vn 0.679581 0.085468 0.728605 -vn 0.603081 -0.136554 0.785905 -vn 0.679581 0.085468 0.728605 -vn 0.559013 0.035015 0.828420 -vn 0.785908 -0.136554 0.603077 -vn 0.848748 -0.198912 0.489960 -vn 0.865986 0.007573 0.500011 -vn 0.865986 0.007573 0.500011 -vn 0.679581 0.085468 0.728605 -vn 0.785908 -0.136554 0.603077 -vn 0.628648 -0.548296 0.551520 -vn 0.619062 -0.625306 0.475137 -vn 0.785908 -0.136554 0.603077 -vn 0.785908 -0.136554 0.603077 -vn 0.692977 -0.198918 0.692975 -vn 0.628648 -0.548296 0.551520 -vn 0.695502 -0.548117 0.464591 -vn 0.675878 -0.625313 0.390093 -vn 0.848748 -0.198912 0.489960 -vn 0.695502 -0.548117 0.464591 -vn 0.848748 -0.198912 0.489960 -vn 0.785908 -0.136554 0.603077 -vn 0.619062 -0.625306 0.475137 -vn 0.158405 -0.979857 0.121607 -vn 0.166042 -0.979858 0.110944 -vn 0.695502 -0.548117 0.464591 -vn 0.166042 -0.979858 0.110944 -vn 0.172924 -0.979863 0.099831 -vn 0.166042 -0.979858 0.110944 -vn -0.066515 -0.996795 -0.044445 -vn -0.069281 -0.996795 -0.039999 -vn 0.158405 -0.979857 0.121607 -vn -0.063454 -0.996795 -0.048715 -vn -0.066515 -0.996795 -0.044445 -vn 0.551796 -0.625317 0.551816 -vn 0.141165 -0.979865 0.141202 -vn 0.150082 -0.979862 0.131702 -vn 0.628648 -0.548296 0.551520 -vn 0.150082 -0.979862 0.131702 -vn 0.158405 -0.979857 0.121607 -vn 0.150082 -0.979862 0.131702 -vn -0.060129 -0.996795 -0.052767 -vn -0.063454 -0.996795 -0.048715 -vn 0.141165 -0.979865 0.141202 -vn -0.056560 -0.996795 -0.056577 -vn -0.060129 -0.996795 -0.052767 -vn 0.464580 -0.548113 0.695513 -vn 0.475115 -0.625305 0.619080 -vn 0.603081 -0.136554 0.785905 -vn 0.603081 -0.136554 0.785905 -vn 0.489963 -0.198913 0.848746 -vn 0.464580 -0.548113 0.695513 -vn 0.551508 -0.548294 0.628659 -vn 0.551796 -0.625317 0.551816 -vn 0.692977 -0.198918 0.692975 -vn 0.551508 -0.548294 0.628659 -vn 0.692977 -0.198918 0.692975 -vn 0.603081 -0.136554 0.785905 -vn 0.475115 -0.625305 0.619080 -vn 0.121566 -0.979857 0.158438 -vn 0.131662 -0.979863 0.150115 -vn 0.551508 -0.548294 0.628659 -vn 0.131662 -0.979863 0.150115 -vn 0.141165 -0.979865 0.141202 -vn 0.131662 -0.979863 0.150115 -vn -0.052748 -0.996795 -0.060144 -vn -0.056560 -0.996795 -0.056577 -vn 0.121566 -0.979857 0.158438 -vn -0.048696 -0.996795 -0.063468 -vn -0.052748 -0.996795 -0.060144 -vn 0.390067 -0.625315 0.675892 -vn 0.099785 -0.979863 0.172949 -vn 0.110900 -0.979858 0.166071 -vn 0.464580 -0.548113 0.695513 -vn 0.110900 -0.979858 0.166071 -vn 0.121566 -0.979857 0.158438 -vn 0.110900 -0.979858 0.166071 -vn -0.044424 -0.996795 -0.066528 -vn -0.048696 -0.996795 -0.063468 -vn 0.099785 -0.979863 0.172949 -vn -0.039978 -0.996795 -0.069293 -vn -0.044424 -0.996795 -0.066528 -vn 0.499945 0.102956 0.859916 -vn 0.500192 0.089907 0.861234 -vn 0.863780 0.089908 0.495782 -vn 0.862907 0.102956 0.494765 -vn 0.863780 0.089908 0.495782 -vn 0.995947 0.089909 -0.002546 -vn 0.863780 0.089908 0.495782 -vn 0.864783 0.062737 0.498211 -vn 0.998889 0.047128 -0.000794 -vn 0.500192 0.089907 0.861234 -vn 0.522059 0.054243 0.851183 -vn 0.864783 0.062737 0.498211 -vn 0.861619 0.119288 0.493338 -vn 0.862116 0.112906 0.493972 -vn 0.993600 0.112908 -0.003282 -vn 0.862116 0.112906 0.493972 -vn 0.862907 0.102956 0.494765 -vn 0.994681 0.102958 -0.002990 -vn 0.499657 0.112906 0.858834 -vn 0.499945 0.102956 0.859916 -vn 0.862907 0.102956 0.494765 -vn -0.863839 0.062737 0.499846 -vn -0.998889 0.047128 0.000794 -vn -0.998818 0.048476 0.003588 -vn -0.863839 0.062737 0.499846 -vn -0.998818 0.048476 0.003588 -vn -0.972486 0.075824 0.220276 -vn -0.520588 0.054246 0.852083 -vn -0.559013 0.035015 0.828420 -vn -0.224256 0.085466 0.970775 -vn -0.224256 0.085466 0.970775 -vn 0.000000 0.054620 0.998507 -vn -0.520588 0.054246 0.852083 -vn 0.224256 0.085466 0.970775 -vn 0.559013 0.035015 0.828420 -vn 0.522059 0.054243 0.851183 -vn 0.522059 0.054243 0.851183 -vn 0.000000 0.054620 0.998507 -vn 0.224256 0.085466 0.970775 -vn 0.129333 -0.136787 0.982121 -vn 0.253603 -0.198906 0.946637 -vn 0.224256 0.085466 0.970775 -vn 0.129333 -0.136787 0.982121 -vn 0.224256 0.085466 0.970775 -vn 0.000000 0.054620 0.998507 -vn 0.379146 -0.136670 0.915188 -vn 0.489963 -0.198913 0.848746 -vn 0.559013 0.035015 0.828420 -vn 0.379146 -0.136670 0.915188 -vn 0.559013 0.035015 0.828420 -vn 0.224256 0.085466 0.970775 -vn 0.268901 -0.548039 0.792052 -vn 0.298761 -0.625313 0.720920 -vn 0.379146 -0.136670 0.915188 -vn 0.268901 -0.548039 0.792052 -vn 0.379146 -0.136670 0.915188 -vn 0.253603 -0.198906 0.946637 -vn 0.369884 -0.548374 0.749982 -vn 0.390067 -0.625315 0.675892 -vn 0.489963 -0.198913 0.848746 -vn 0.369884 -0.548374 0.749982 -vn 0.489963 -0.198913 0.848746 -vn 0.379146 -0.136670 0.915188 -vn 0.298761 -0.625313 0.720920 -vn 0.076426 -0.979861 0.184474 -vn 0.088294 -0.979865 0.179080 -vn 0.369884 -0.548374 0.749982 -vn 0.088294 -0.979865 0.179080 -vn 0.099785 -0.979863 0.172949 -vn 0.088294 -0.979865 0.179080 -vn -0.035375 -0.996795 -0.071753 -vn -0.039978 -0.996795 -0.069293 -vn 0.076426 -0.979861 0.184474 -vn -0.030617 -0.996795 -0.073907 -vn -0.035375 -0.996795 -0.071753 -vn 0.201834 -0.625309 0.753825 -vn 0.051625 -0.979859 0.192902 -vn 0.064178 -0.979856 0.189113 -vn 0.268901 -0.548039 0.792052 -vn 0.064178 -0.979856 0.189113 -vn 0.076426 -0.979861 0.184474 -vn 0.064178 -0.979856 0.189113 -vn -0.025707 -0.996795 -0.075754 -vn -0.030617 -0.996795 -0.073907 -vn 0.051625 -0.979859 0.192902 -vn -0.020680 -0.996795 -0.077279 -vn -0.025707 -0.996795 -0.075754 -vn 0.054845 -0.548214 0.834538 -vn 0.101911 -0.625316 0.773688 -vn 0.129333 -0.136787 0.982121 -vn 0.054845 -0.548214 0.834538 -vn 0.129333 -0.136787 0.982121 -vn 0.000000 -0.198908 0.980018 -vn 0.163032 -0.548348 0.820204 -vn 0.201834 -0.625309 0.753825 -vn 0.253603 -0.198906 0.946637 -vn 0.253603 -0.198906 0.946637 -vn 0.129333 -0.136787 0.982121 -vn 0.163032 -0.548348 0.820204 -vn 0.101911 -0.625316 0.773688 -vn 0.026053 -0.979864 0.197959 -vn 0.038902 -0.979864 0.195841 -vn 0.163032 -0.548348 0.820204 -vn 0.038902 -0.979864 0.195841 -vn 0.051625 -0.979859 0.192902 -vn 0.038902 -0.979864 0.195841 -vn -0.015585 -0.996795 -0.078466 -vn -0.020680 -0.996795 -0.077279 -vn 0.026053 -0.979864 0.197959 -vn -0.010437 -0.996795 -0.079315 -vn -0.015585 -0.996795 -0.078466 -vn -0.000016 -0.625302 0.780383 -vn -0.000027 -0.979855 0.199708 -vn 0.013072 -0.979860 0.199255 -vn 0.054845 -0.548214 0.834538 -vn 0.013072 -0.979860 0.199255 -vn 0.026053 -0.979864 0.197959 -vn 0.013072 -0.979860 0.199255 -vn -0.005235 -0.996795 -0.079826 -vn -0.010437 -0.996795 -0.079315 -vn -0.000027 -0.979855 0.199708 -vn 0.000012 -0.996795 -0.079997 -vn -0.005235 -0.996795 -0.079826 -vn -0.379146 -0.136670 0.915188 -vn -0.253603 -0.198906 0.946637 -vn -0.224256 0.085466 0.970775 -vn -0.224256 0.085466 0.970775 -vn -0.559013 0.035015 0.828420 -vn -0.379146 -0.136670 0.915188 -vn -0.129333 -0.136787 0.982121 -vn 0.000000 -0.198908 0.980018 -vn 0.000000 0.054620 0.998507 -vn 0.000000 0.054620 0.998507 -vn -0.224256 0.085466 0.970775 -vn -0.129333 -0.136787 0.982121 -vn -0.163052 -0.548348 0.820200 -vn -0.101942 -0.625316 0.773684 -vn -0.129333 -0.136787 0.982121 -vn -0.163052 -0.548348 0.820200 -vn -0.129333 -0.136787 0.982121 -vn -0.253603 -0.198906 0.946637 -vn -0.054866 -0.548214 0.834537 -vn -0.000016 -0.625302 0.780383 -vn 0.000000 -0.198908 0.980018 -vn 0.000000 -0.198908 0.980018 -vn -0.129333 -0.136787 0.982121 -vn -0.054866 -0.548214 0.834537 -vn -0.101942 -0.625316 0.773684 -vn -0.026105 -0.979864 0.197952 -vn -0.013125 -0.979860 0.199252 -vn -0.054866 -0.548214 0.834537 -vn -0.013125 -0.979860 0.199252 -vn -0.000027 -0.979855 0.199708 -vn -0.013125 -0.979860 0.199252 -vn 0.005260 -0.996795 -0.079825 -vn 0.000012 -0.996795 -0.079997 -vn -0.026105 -0.979864 0.197952 -vn 0.010461 -0.996795 -0.079312 -vn 0.005260 -0.996795 -0.079825 -vn -0.201864 -0.625309 0.753817 -vn -0.051676 -0.979859 0.192887 -vn -0.038954 -0.979864 0.195830 -vn -0.163052 -0.548348 0.820200 -vn -0.038954 -0.979864 0.195830 -vn -0.026105 -0.979864 0.197952 -vn -0.038954 -0.979864 0.195830 -vn 0.015609 -0.996795 -0.078461 -vn 0.010461 -0.996795 -0.079312 -vn -0.051676 -0.979859 0.192887 -vn 0.020704 -0.996795 -0.077272 -vn 0.015609 -0.996795 -0.078461 -vn -0.369902 -0.548374 0.749972 -vn -0.298790 -0.625312 0.720908 -vn -0.379146 -0.136670 0.915188 -vn -0.379146 -0.136670 0.915188 -vn -0.489963 -0.198913 0.848746 -vn -0.369902 -0.548374 0.749972 -vn -0.268920 -0.548039 0.792045 -vn -0.201864 -0.625309 0.753817 -vn -0.253603 -0.198906 0.946637 -vn -0.253603 -0.198906 0.946637 -vn -0.379146 -0.136670 0.915188 -vn -0.268920 -0.548039 0.792045 -vn -0.298790 -0.625312 0.720908 -vn -0.076475 -0.979861 0.184454 -vn -0.064229 -0.979856 0.189096 -vn -0.268920 -0.548039 0.792045 -vn -0.064229 -0.979856 0.189096 -vn -0.051676 -0.979859 0.192887 -vn -0.064229 -0.979856 0.189096 -vn 0.025730 -0.996795 -0.075746 -vn 0.020704 -0.996795 -0.077272 -vn -0.076475 -0.979861 0.184454 -vn 0.030640 -0.996795 -0.073898 -vn 0.025730 -0.996795 -0.075746 -vn -0.390094 -0.625314 0.675876 -vn -0.099830 -0.979863 0.172922 -vn -0.088341 -0.979865 0.179057 -vn -0.369902 -0.548374 0.749972 -vn -0.088341 -0.979865 0.179057 -vn -0.076475 -0.979861 0.184454 -vn -0.088341 -0.979865 0.179057 -vn 0.035397 -0.996795 -0.071742 -vn 0.030640 -0.996795 -0.073898 -vn -0.099830 -0.979863 0.172922 -vn 0.039999 -0.996795 -0.069281 -vn 0.035397 -0.996795 -0.071742 -vn -0.863839 0.062737 0.499846 -vn -0.865986 0.007573 0.500011 -vn -0.679581 0.085468 0.728605 -vn -0.679581 0.085468 0.728605 -vn -0.559013 0.035015 0.828420 -vn -0.863839 0.062737 0.499846 -vn -0.785908 -0.136554 0.603077 -vn -0.692977 -0.198918 0.692975 -vn -0.679581 0.085468 0.728605 -vn -0.785908 -0.136554 0.603077 -vn -0.679581 0.085468 0.728605 -vn -0.865986 0.007573 0.500011 -vn -0.603081 -0.136554 0.785905 -vn -0.489963 -0.198913 0.848746 -vn -0.559013 0.035015 0.828420 -vn -0.559013 0.035015 0.828420 -vn -0.679581 0.085468 0.728605 -vn -0.603081 -0.136554 0.785905 -vn -0.551523 -0.548295 0.628645 -vn -0.475140 -0.625305 0.619061 -vn -0.603081 -0.136554 0.785905 -vn -0.603081 -0.136554 0.785905 -vn -0.692977 -0.198918 0.692975 -vn -0.551523 -0.548295 0.628645 -vn -0.464597 -0.548113 0.695501 -vn -0.390094 -0.625314 0.675876 -vn -0.489963 -0.198913 0.848746 -vn -0.464597 -0.548113 0.695501 -vn -0.489963 -0.198913 0.848746 -vn -0.603081 -0.136554 0.785905 -vn -0.475140 -0.625305 0.619061 -vn -0.121608 -0.979857 0.158406 -vn -0.110944 -0.979858 0.166042 -vn -0.464597 -0.548113 0.695501 -vn -0.110944 -0.979858 0.166042 -vn -0.099830 -0.979863 0.172922 -vn -0.110944 -0.979858 0.166042 -vn 0.044445 -0.996795 -0.066514 -vn 0.039999 -0.996795 -0.069281 -vn -0.121608 -0.979857 0.158406 -vn 0.048715 -0.996795 -0.063453 -vn 0.044445 -0.996795 -0.066514 -vn -0.551819 -0.625315 0.551794 -vn -0.141203 -0.979865 0.141164 -vn -0.131702 -0.979863 0.150080 -vn -0.551523 -0.548295 0.628645 -vn -0.131702 -0.979863 0.150080 -vn -0.121608 -0.979857 0.158406 -vn -0.131702 -0.979863 0.150080 -vn 0.052767 -0.996795 -0.060128 -vn 0.048715 -0.996795 -0.063453 -vn -0.141203 -0.979865 0.141164 -vn 0.056577 -0.996795 -0.056559 -vn 0.052767 -0.996795 -0.060128 -vn -0.695513 -0.548117 0.464574 -vn -0.619082 -0.625304 0.475112 -vn -0.785908 -0.136554 0.603077 -vn -0.785908 -0.136554 0.603077 -vn -0.848748 -0.198912 0.489960 -vn -0.695513 -0.548117 0.464574 -vn -0.628661 -0.548296 0.551504 -vn -0.551819 -0.625315 0.551794 -vn -0.692977 -0.198918 0.692975 -vn -0.628661 -0.548296 0.551504 -vn -0.692977 -0.198918 0.692975 -vn -0.785908 -0.136554 0.603077 -vn -0.619082 -0.625304 0.475112 -vn -0.158439 -0.979857 0.121565 -vn -0.150116 -0.979863 0.131661 -vn -0.628661 -0.548296 0.551504 -vn -0.150116 -0.979863 0.131661 -vn -0.141203 -0.979865 0.141164 -vn -0.150116 -0.979863 0.131661 -vn 0.060145 -0.996795 -0.052748 -vn 0.056577 -0.996795 -0.056559 -vn -0.158439 -0.979857 0.121565 -vn 0.063469 -0.996795 -0.048696 -vn 0.060145 -0.996795 -0.052748 -vn -0.675893 -0.625315 0.390065 -vn -0.172949 -0.979863 0.099784 -vn -0.166073 -0.979858 0.110900 -vn -0.695513 -0.548117 0.464574 -vn -0.166073 -0.979858 0.110900 -vn -0.158439 -0.979857 0.121565 -vn -0.166073 -0.979858 0.110900 -vn 0.066529 -0.996795 -0.044425 -vn 0.063469 -0.996795 -0.048696 -vn -0.172949 -0.979863 0.099784 -vn 0.069293 -0.996795 -0.039977 -vn 0.066529 -0.996795 -0.044425 -vn -0.998818 0.048476 0.003588 -vn -0.974045 -0.216081 0.067421 -vn -0.959759 -0.214953 0.180714 -vn -0.915190 -0.136671 0.379143 -vn -0.848748 -0.198912 0.489960 -vn -0.865986 0.007573 0.500011 -vn -0.915190 -0.136671 0.379143 -vn -0.865986 0.007573 0.500011 -vn -0.972486 0.075824 0.220276 -vn -0.792052 -0.548040 0.268898 -vn -0.720921 -0.625312 0.298759 -vn -0.915190 -0.136671 0.379143 -vn -0.792052 -0.548040 0.268898 -vn -0.915190 -0.136671 0.379143 -vn -0.959759 -0.214953 0.180714 -vn -0.749983 -0.548375 0.369880 -vn -0.675893 -0.625315 0.390065 -vn -0.848748 -0.198912 0.489960 -vn -0.749983 -0.548375 0.369880 -vn -0.848748 -0.198912 0.489960 -vn -0.915190 -0.136671 0.379143 -vn -0.720921 -0.625312 0.298759 -vn -0.184475 -0.979861 0.076425 -vn -0.179081 -0.979865 0.088293 -vn -0.749983 -0.548375 0.369880 -vn -0.179081 -0.979865 0.088293 -vn -0.172949 -0.979863 0.099784 -vn -0.179081 -0.979865 0.088293 -vn 0.071753 -0.996795 -0.035375 -vn 0.069293 -0.996795 -0.039977 -vn -0.184475 -0.979861 0.076425 -vn 0.073908 -0.996795 -0.030617 -vn 0.071753 -0.996795 -0.035375 -vn -0.787262 -0.610234 0.088501 -vn -0.217514 -0.975719 0.025702 -vn -0.189113 -0.979856 0.064178 -vn -0.792052 -0.548040 0.268898 -vn -0.189113 -0.979856 0.064178 -vn -0.184475 -0.979861 0.076425 -vn -0.189113 -0.979856 0.064178 -vn 0.075754 -0.996795 -0.025706 -vn 0.073908 -0.996795 -0.030617 -vn -0.217514 -0.975719 0.025702 -vn 0.079340 -0.996763 -0.012975 -vn 0.075754 -0.996795 -0.025706 -vn -0.959759 -0.214953 0.180714 -vn -0.974045 -0.216081 0.067421 -vn -0.774567 -0.626221 0.088845 -vn -0.787262 -0.610234 0.088501 -vn -0.959759 -0.214953 0.180714 -vn -0.059975 -0.994232 0.088919 -vn -0.217514 -0.975719 0.025702 -vn -0.787262 -0.610234 0.088501 -vn -0.059975 -0.994232 0.088919 -vn -0.195626 -0.976106 0.094593 -vn -0.059975 -0.994232 0.088919 -vn -0.959759 -0.214953 0.180714 -vn -0.959759 -0.214953 0.180714 -vn -0.774567 -0.626221 0.088845 -vn -0.195626 -0.976106 0.094593 -vn -0.493340 0.119288 0.861618 -vn -0.493974 0.112906 0.862115 -vn 0.003282 0.112908 0.993600 -vn -0.494767 0.102956 0.862905 -vn -0.495785 0.089908 0.863779 -vn 0.002546 0.089909 0.995947 -vn 0.002990 0.102958 0.994681 -vn 0.002546 0.089909 0.995947 -vn 0.500192 0.089907 0.861234 -vn 0.002546 0.089909 0.995947 -vn 0.000794 0.047128 0.998889 -vn 0.522059 0.054243 0.851183 -vn -0.495785 0.089908 0.863779 -vn -0.520588 0.054246 0.852083 -vn 0.000794 0.047128 0.998889 -vn 0.003582 0.119290 0.992853 -vn 0.003282 0.112908 0.993600 -vn 0.499657 0.112906 0.858834 -vn 0.003282 0.112908 0.993600 -vn 0.002990 0.102958 0.994681 -vn 0.499945 0.102956 0.859916 -vn -0.493974 0.112906 0.862115 -vn -0.494767 0.102956 0.862905 -vn 0.002990 0.102958 0.994681 -vn -0.994681 0.102958 0.002990 -vn -0.995947 0.089909 0.002546 -vn -0.861235 0.089907 0.500190 -vn -0.859917 0.102956 0.499943 -vn -0.861235 0.089907 0.500190 -vn -0.495785 0.089908 0.863779 -vn -0.861235 0.089907 0.500190 -vn -0.863839 0.062737 0.499846 -vn -0.520588 0.054246 0.852083 -vn -0.995947 0.089909 0.002546 -vn -0.998889 0.047128 0.000794 -vn -0.863839 0.062737 0.499846 -vn -0.858038 0.119288 0.499541 -vn -0.858835 0.112906 0.499655 -vn -0.493974 0.112906 0.862115 -vn -0.858835 0.112906 0.499655 -vn -0.859917 0.102956 0.499943 -vn -0.494767 0.102956 0.862905 -vn -0.993600 0.112908 0.003282 -vn -0.994681 0.102958 0.002990 -vn -0.859917 0.102956 0.499943 -vn 0.499499 0.138592 0.855157 -vn 0.499269 0.137445 0.855476 -vn 0.860102 0.137445 0.491258 -vn 0.499366 0.128646 0.856787 -vn 0.499410 0.124651 0.857352 -vn 0.861162 0.124651 0.492811 -vn 0.860841 0.128646 0.492344 -vn 0.861162 0.124651 0.492811 -vn 0.992193 0.124653 -0.003810 -vn 0.861162 0.124651 0.492811 -vn 0.861619 0.119288 0.493338 -vn 0.992853 0.119290 -0.003582 -vn 0.499410 0.124651 0.857352 -vn 0.499543 0.119288 0.858037 -vn 0.861619 0.119288 0.493338 -vn 0.499299 0.134937 0.855858 -vn 0.499292 0.132157 0.856295 -vn 0.860531 0.132157 0.491956 -vn 0.860318 0.134936 0.491574 -vn 0.860531 0.132157 0.491956 -vn 0.991220 0.132159 -0.004236 -vn 0.860531 0.132157 0.491956 -vn 0.860841 0.128646 0.492344 -vn 0.991682 0.128649 -0.004054 -vn 0.499292 0.132157 0.856295 -vn 0.499366 0.128646 0.856787 -vn 0.860841 0.128646 0.492344 -vn 0.860140 0.138592 0.490867 -vn 0.860102 0.137445 0.491258 -vn 0.990498 0.137448 -0.004625 -vn 0.860102 0.137445 0.491258 -vn 0.860318 0.134936 0.491574 -vn 0.990844 0.134939 -0.004460 -vn 0.499269 0.137445 0.855476 -vn 0.499299 0.134937 0.855858 -vn 0.860318 0.134936 0.491574 -vn -0.991682 0.128649 0.004054 -vn -0.992193 0.124653 0.003810 -vn -0.857353 0.124650 0.499408 -vn -0.492346 0.128646 0.860840 -vn -0.492814 0.124651 0.861160 -vn 0.003810 0.124653 0.992193 -vn 0.004054 0.128649 0.991682 -vn 0.003810 0.124653 0.992193 -vn 0.499410 0.124651 0.857352 -vn 0.003810 0.124653 0.992193 -vn 0.003582 0.119290 0.992853 -vn 0.499543 0.119288 0.858037 -vn -0.492814 0.124651 0.861160 -vn -0.493340 0.119288 0.861618 -vn 0.003582 0.119290 0.992853 -vn -0.856788 0.128646 0.499364 -vn -0.857353 0.124650 0.499408 -vn -0.492814 0.124651 0.861160 -vn -0.857353 0.124650 0.499408 -vn -0.858038 0.119288 0.499541 -vn -0.493340 0.119288 0.861618 -vn -0.992193 0.124653 0.003810 -vn -0.992853 0.119290 0.003582 -vn -0.858038 0.119288 0.499541 -vn -0.490869 0.138592 0.860139 -vn -0.491260 0.137445 0.860100 -vn 0.004625 0.137448 0.990498 -vn -0.491576 0.134936 0.860317 -vn -0.491957 0.132157 0.860530 -vn 0.004236 0.132159 0.991220 -vn 0.004460 0.134939 0.990844 -vn 0.004236 0.132159 0.991220 -vn 0.499292 0.132157 0.856295 -vn 0.004236 0.132159 0.991220 -vn 0.004054 0.128649 0.991682 -vn 0.499366 0.128646 0.856787 -vn -0.491957 0.132157 0.860530 -vn -0.492346 0.128646 0.860840 -vn 0.004054 0.128649 0.991682 -vn 0.004983 0.138595 0.990337 -vn 0.004625 0.137448 0.990498 -vn 0.499269 0.137445 0.855476 -vn 0.004625 0.137448 0.990498 -vn 0.004460 0.134939 0.990844 -vn 0.499299 0.134937 0.855858 -vn -0.491260 0.137445 0.860100 -vn -0.491576 0.134936 0.860317 -vn 0.004460 0.134939 0.990844 -vn -0.990844 0.134939 0.004460 -vn -0.991220 0.132159 0.004236 -vn -0.856296 0.132157 0.499291 -vn -0.855859 0.134936 0.499297 -vn -0.856296 0.132157 0.499291 -vn -0.491957 0.132157 0.860530 -vn -0.856296 0.132157 0.499291 -vn -0.856788 0.128646 0.499364 -vn -0.492346 0.128646 0.860840 -vn -0.991220 0.132159 0.004236 -vn -0.991682 0.128649 0.004054 -vn -0.856788 0.128646 0.499364 -vn -0.855158 0.138592 0.499497 -vn -0.855477 0.137445 0.499267 -vn -0.491260 0.137445 0.860100 -vn -0.855477 0.137445 0.499267 -vn -0.855859 0.134936 0.499297 -vn -0.491576 0.134936 0.860317 -vn -0.990498 0.137448 0.004625 -vn -0.990844 0.134939 0.004460 -vn -0.855859 0.134936 0.499297 -s off -g glass:revolvedSurface2 -usemtl initialShadingGroup -f 481/1/1 2/2/2 482/3/3 -f 260/4/4 3/5/5 261/6/6 -f 220/7/7 6/8/8 221/9/9 -f 81/10/10 7/11/11 83/12/12 -f 11/13/13 10/14/14 46/15/15 -f 13/16/16 9/17/17 11/13/18 -f 14/18/19 33/19/20 35/20/21 -f 15/21/22 18/22/23 19/23/24 -f 18/22/25 28/24/26 30/25/27 -f 19/23/28 22/26/29 23/27/30 -f 23/27/31 22/26/32 26/28/33 -f 25/29/34 21/30/35 23/27/36 -f 1/31/37 25/29/38 26/28/39 -f 24/32/40 26/28/41 27/33/42 -f 31/34/43 30/25/44 28/24/45 -f 27/33/46 22/26/47 30/25/48 -f 20/35/49 27/33/50 31/34/51 -f 29/36/52 31/34/53 32/37/54 -f 33/19/55 41/38/56 43/39/57 -f 35/20/58 36/40/59 38/41/60 -f 39/42/61 38/41/62 36/40/63 -f 32/37/64 28/24/65 38/41/66 -f 16/43/67 32/37/68 39/42/69 -f 37/44/70 39/42/71 40/45/72 -f 44/46/73 43/39/74 41/38/75 -f 40/45/76 36/40/77 43/39/78 -f 34/47/79 40/45/80 44/46/81 -f 42/48/82 44/46/83 45/49/84 -f 64/50/85 49/51/86 48/52/87 -f 48/52/88 49/51/89 51/53/90 -f 49/51/91 57/54/92 59/55/93 -f 51/53/94 52/56/95 54/57/96 -f 55/58/97 54/57/98 52/56/99 -f 45/49/100 41/38/101 54/57/102 -f 12/59/103 45/49/104 55/58/105 -f 53/60/106 55/58/107 56/61/108 -f 60/62/109 59/55/110 57/54/111 -f 56/61/112 52/56/113 59/55/114 -f 50/63/115 56/61/116 60/62/117 -f 58/64/118 60/62/119 61/65/120 -f 62/66/121 70/67/122 72/68/123 -f 64/50/124 65/69/125 67/70/126 -f 68/71/127 67/70/128 65/69/129 -f 61/65/130 57/54/131 67/70/132 -f 47/72/133 61/65/134 68/71/135 -f 66/73/136 68/71/137 69/74/138 -f 73/75/139 72/68/140 70/67/141 -f 69/74/142 65/69/143 72/68/144 -f 63/76/145 69/74/146 73/75/147 -f 71/77/148 73/75/149 74/78/150 -f 77/79/151 76/80/152 79/81/153 -f 78/82/154 75/83/155 77/79/156 -f 9/17/157 78/82/158 79/81/159 -f 11/13/160 79/81/161 80/84/162 -f 82/85/163 5/86/164 81/10/165 -f 75/83/166 82/85/167 83/12/168 -f 77/79/169 83/12/170 84/87/171 -f 181/88/172 150/89/173 149/90/174 -f 90/91/175 89/92/176 87/93/177 -f 10/14/178 89/92/179 90/91/180 -f 90/91/181 106/94/182 108/95/183 -f 92/96/184 93/97/185 95/98/186 -f 93/97/187 101/99/188 103/100/189 -f 95/98/190 96/101/191 98/102/192 -f 99/103/193 98/102/194 96/101/195 -f 74/78/196 70/67/197 98/102/198 -f 8/104/199 74/78/200 99/103/201 -f 97/105/202 99/103/203 100/106/204 -f 104/107/205 103/100/206 101/99/207 -f 100/106/208 96/101/209 103/100/210 -f 94/108/211 100/106/212 104/107/213 -f 102/109/214 104/107/215 105/110/216 -f 106/94/217 114/111/218 116/112/219 -f 108/95/220 109/113/221 111/114/222 -f 112/115/223 111/114/224 109/113/225 -f 105/110/226 101/99/227 111/114/228 -f 91/116/229 105/110/230 112/115/231 -f 110/117/232 112/115/233 113/118/234 -f 117/119/235 116/112/236 114/111/237 -f 113/118/238 109/113/239 116/112/240 -f 107/120/241 113/118/242 117/119/243 -f 115/121/244 117/119/245 118/122/246 -f 119/123/247 135/124/248 137/125/249 -f 121/126/250 122/127/251 124/128/252 -f 122/127/253 130/129/254 132/130/255 -f 124/128/256 125/131/257 127/132/258 -f 128/133/259 127/132/260 125/131/261 -f 118/122/262 114/111/263 127/132/264 -f 88/134/265 118/122/266 128/133/267 -f 126/135/268 128/133/269 129/136/270 -f 133/137/271 132/130/272 130/129/273 -f 129/136/274 125/131/275 132/130/276 -f 123/138/277 129/136/278 133/137/279 -f 131/139/280 133/137/281 134/140/282 -f 135/124/283 143/141/284 145/142/285 -f 137/125/286 138/143/287 140/144/288 -f 141/145/289 140/144/290 138/143/291 -f 134/140/292 130/129/293 140/144/294 -f 120/146/295 134/140/296 141/145/297 -f 139/147/298 141/145/299 142/148/300 -f 146/149/301 145/142/302 143/141/303 -f 142/148/304 138/143/305 145/142/306 -f 136/150/307 142/148/308 146/149/309 -f 144/151/310 146/149/311 147/152/312 -f 119/123/313 87/93/314 149/90/315 -f 150/89/316 166/153/317 168/154/318 -f 152/155/319 153/156/320 155/157/321 -f 153/156/322 161/158/323 163/159/324 -f 155/157/325 156/160/326 158/161/327 -f 159/162/328 158/161/329 156/160/330 -f 147/152/331 143/141/332 158/161/333 -f 86/163/334 147/152/335 159/162/336 -f 157/164/337 159/162/338 160/165/339 -f 164/166/340 163/159/341 161/158/342 -f 160/165/343 156/160/344 163/159/345 -f 154/167/346 160/165/347 164/166/348 -f 162/168/349 164/166/350 165/169/351 -f 166/153/352 174/170/353 176/171/354 -f 168/154/355 169/172/356 171/173/357 -f 172/174/358 171/173/359 169/172/360 -f 165/169/361 161/158/362 171/173/363 -f 151/175/364 165/169/365 172/174/366 -f 170/176/367 172/174/368 173/177/369 -f 177/178/370 176/171/371 174/170/372 -f 173/177/373 169/172/374 176/171/375 -f 167/179/376 173/177/377 177/178/378 -f 175/180/379 177/178/380 178/181/381 -f 197/182/382 182/183/383 181/88/384 -f 181/88/385 182/183/386 184/184/387 -f 182/183/388 190/185/389 192/186/390 -f 184/184/391 185/187/392 187/188/393 -f 188/189/394 187/188/395 185/187/396 -f 178/181/397 174/170/398 187/188/399 -f 148/190/400 178/181/401 188/189/402 -f 186/191/403 188/189/404 189/192/405 -f 193/193/406 192/186/407 190/185/408 -f 189/192/409 185/187/410 192/186/411 -f 183/194/412 189/192/413 193/193/414 -f 191/195/415 193/193/416 194/196/417 -f 205/197/418 198/198/419 197/182/420 -f 197/182/421 198/198/422 200/199/423 -f 201/200/424 200/199/425 198/198/426 -f 194/196/427 190/185/428 200/199/429 -f 180/201/430 194/196/431 201/200/432 -f 199/202/433 201/200/434 202/203/435 -f 206/204/436 205/197/437 203/205/438 -f 202/203/439 198/198/440 205/197/441 -f 196/206/442 202/203/443 206/204/444 -f 204/207/445 206/204/446 207/208/447 -f 213/209/448 208/210/449 214/211/450 -f 211/212/451 210/213/452 209/214/453 -f 80/84/454 76/80/455 210/213/456 -f 10/14/457 80/84/458 211/212/459 -f 89/92/460 211/212/461 212/215/462 -f 7/11/463 213/209/464 84/87/465 -f 76/80/466 84/87/467 214/211/468 -f 210/213/469 214/211/470 215/216/471 -f 218/217/472 217/218/473 216/219/474 -f 212/215/475 209/214/476 217/218/477 -f 87/93/478 212/215/479 218/217/480 -f 149/90/481 218/217/482 219/220/483 -f 208/210/484 220/7/485 215/216/486 -f 209/214/487 215/216/488 221/9/489 -f 217/218/490 221/9/491 222/221/492 -f 236/222/493 223/223/494 238/224/495 -f 226/225/496 225/226/497 228/227/498 -f 227/228/499 224/229/500 226/225/501 -f 5/86/502 227/228/503 228/227/504 -f 81/10/505 228/227/506 229/230/507 -f 232/231/508 231/232/509 234/233/510 -f 233/234/511 230/235/512 232/231/513 -f 224/229/514 233/234/515 234/233/516 -f 226/225/517 234/233/518 235/236/519 -f 237/237/520 2/238/521 236/222/522 -f 230/235/523 237/237/524 238/224/525 -f 232/231/526 238/224/527 239/239/528 -f 246/240/529 245/241/530 240/242/531 -f 243/243/532 242/244/533 241/245/534 -f 229/230/535 225/226/536 242/244/537 -f 7/11/538 229/230/539 243/243/540 -f 213/209/541 243/243/542 244/246/543 -f 244/246/544 241/245/545 245/241/546 -f 208/210/547 244/246/548 246/240/549 -f 220/7/550 246/240/551 247/247/552 -f 253/248/553 248/249/554 254/250/555 -f 251/251/556 250/252/557 249/253/558 -f 235/236/559 231/232/560 250/252/561 -f 225/226/562 235/236/563 251/251/564 -f 242/244/565 251/251/566 252/254/567 -f 223/223/568 253/248/569 239/239/570 -f 231/232/571 239/239/572 254/250/573 -f 250/252/574 254/250/575 255/255/576 -f 258/256/577 257/257/578 256/258/579 -f 252/254/580 249/253/581 257/257/582 -f 241/245/583 252/254/584 258/256/585 -f 245/241/586 258/256/587 259/259/588 -f 248/249/589 260/4/590 255/255/591 -f 249/253/592 255/255/593 261/6/594 -f 257/257/595 261/6/596 262/260/597 -f 452/261/598 451/262/599 5/263/600 -f 330/264/601 264/265/602 331/266/603 -f 267/267/604 265/268/605 297/269/606 -f 179/270/607 85/271/608 267/267/609 -f 268/272/610 284/273/611 286/274/612 -f 270/275/613 271/276/614 273/277/615 -f 271/276/616 279/278/617 281/279/618 -f 273/277/619 274/280/620 276/281/621 -f 277/282/622 276/281/623 274/280/624 -f 207/208/625 203/205/626 276/281/627 -f 4/283/628 207/208/629 277/282/630 -f 275/284/631 277/282/632 278/285/633 -f 282/286/634 281/279/635 279/278/636 -f 278/285/637 274/280/638 281/279/639 -f 272/287/640 278/285/641 282/286/642 -f 280/288/643 282/286/644 283/289/645 -f 284/273/646 292/290/647 294/291/648 -f 286/274/649 287/292/650 289/293/651 -f 290/294/652 289/293/653 287/292/654 -f 283/289/655 279/278/656 289/293/657 -f 269/295/658 283/289/659 290/294/660 -f 288/296/661 290/294/662 291/297/663 -f 295/298/664 294/291/665 292/290/666 -f 291/297/667 287/292/668 294/291/669 -f 285/299/670 291/297/671 295/298/672 -f 293/300/673 295/298/674 296/301/675 -f 297/269/676 313/302/677 315/303/678 -f 299/304/679 300/305/680 302/306/681 -f 300/305/682 308/307/683 310/308/684 -f 302/306/685 303/309/686 305/310/687 -f 306/311/688 305/310/689 303/309/690 -f 296/301/691 292/290/692 305/310/693 -f 266/312/694 296/301/695 306/311/696 -f 304/313/697 306/311/698 307/314/699 -f 311/315/700 310/308/701 308/307/702 -f 307/314/703 303/309/704 310/308/705 -f 301/316/706 307/314/707 311/315/708 -f 309/317/709 311/315/710 312/318/711 -f 313/302/712 321/319/713 323/320/714 -f 315/303/715 316/321/716 318/322/717 -f 319/323/718 318/322/719 316/321/720 -f 312/318/721 308/307/722 318/322/723 -f 298/324/724 312/318/725 319/323/726 -f 317/325/727 319/323/728 320/326/729 -f 324/327/730 323/320/731 321/319/732 -f 320/326/733 316/321/734 323/320/735 -f 314/328/736 320/326/737 324/327/738 -f 322/329/739 324/327/740 325/330/741 -f 327/331/742 326/332/743 328/333/744 -f 219/220/745 216/219/746 327/331/747 -f 85/271/748 219/220/749 328/333/750 -f 267/267/751 328/333/752 329/334/753 -f 222/221/754 6/8/755 330/264/756 -f 216/219/757 222/221/758 331/266/759 -f 327/331/760 331/266/761 332/335/762 -f 427/336/763 397/337/764 396/338/765 -f 337/339/766 336/340/767 334/341/768 -f 265/268/769 336/340/770 337/339/771 -f 337/339/772 353/342/773 355/343/774 -f 339/344/775 340/345/776 342/346/777 -f 340/345/778 348/347/779 350/348/780 -f 342/346/781 343/349/782 345/350/783 -f 346/351/784 345/350/785 343/349/786 -f 325/330/787 321/319/788 345/350/789 -f 263/352/790 325/330/791 346/351/792 -f 344/353/793 346/351/794 347/354/795 -f 351/355/796 350/348/797 348/347/798 -f 347/354/799 343/349/800 350/348/801 -f 341/356/802 347/354/803 351/355/804 -f 349/357/805 351/355/806 352/358/807 -f 353/342/808 361/359/809 363/360/810 -f 355/343/811 356/361/812 358/362/813 -f 359/363/814 358/362/815 356/361/816 -f 352/358/817 348/347/818 358/362/819 -f 338/364/820 352/358/821 359/363/822 -f 357/365/823 359/363/824 360/366/825 -f 364/367/826 363/360/827 361/359/828 -f 360/366/829 356/361/830 363/360/831 -f 354/368/832 360/366/833 364/367/834 -f 362/369/835 364/367/836 365/370/837 -f 366/371/838 382/372/839 384/373/840 -f 368/374/841 369/375/842 371/376/843 -f 369/375/844 377/377/845 379/378/846 -f 371/376/847 372/379/848 374/380/849 -f 375/381/850 374/380/851 372/379/852 -f 365/370/853 361/359/854 374/380/855 -f 335/382/856 365/370/857 375/381/858 -f 373/383/859 375/381/860 376/384/861 -f 380/385/862 379/378/863 377/377/864 -f 376/384/865 372/379/866 379/378/867 -f 370/386/868 376/384/869 380/385/870 -f 378/387/871 380/385/872 381/388/873 -f 382/372/874 390/389/875 392/390/876 -f 384/373/877 385/391/878 387/392/879 -f 388/393/880 387/392/881 385/391/882 -f 381/388/883 377/377/884 387/392/885 -f 367/394/886 381/388/887 388/393/888 -f 386/395/889 388/393/890 389/396/891 -f 393/397/892 392/390/893 390/389/894 -f 389/396/895 385/391/896 392/390/897 -f 383/398/898 389/396/899 393/397/900 -f 391/399/901 393/397/902 394/400/903 -f 366/371/904 334/341/905 396/338/906 -f 397/337/907 413/401/908 415/402/909 -f 399/403/910 400/404/911 402/405/912 -f 400/404/913 408/406/914 410/407/915 -f 402/405/916 403/408/917 405/409/918 -f 406/410/919 405/409/920 403/408/921 -f 394/400/922 390/389/923 405/409/924 -f 333/411/925 394/400/926 406/410/927 -f 404/412/928 406/410/929 407/413/930 -f 411/414/931 410/407/932 408/406/933 -f 407/413/934 403/408/935 410/407/936 -f 401/415/937 407/413/938 411/414/939 -f 409/416/940 411/414/941 412/417/942 -f 413/401/943 421/418/944 423/419/945 -f 415/402/946 416/420/947 418/421/948 -f 419/422/949 418/421/950 416/420/951 -f 412/417/952 408/406/953 418/421/954 -f 398/423/955 412/417/956 419/422/957 -f 417/424/958 419/422/959 420/425/960 -f 424/426/961 423/419/962 421/418/963 -f 420/425/964 416/420/965 423/419/966 -f 414/427/967 420/425/968 424/426/969 -f 422/428/970 424/426/971 425/429/972 -f 428/430/973 427/336/974 13/431/975 -f 427/336/976 428/430/977 430/432/978 -f 428/430/979 436/433/980 438/434/981 -f 430/432/982 431/435/983 433/436/984 -f 434/437/985 433/436/986 431/435/987 -f 425/429/988 421/418/989 433/436/990 -f 395/438/991 425/429/992 434/437/993 -f 432/439/994 434/437/995 435/440/996 -f 439/441/997 438/434/998 436/433/999 -f 435/440/1000 431/435/1001 438/434/1002 -f 429/442/1003 435/440/1004 439/441/1005 -f 437/443/1006 439/441/1007 440/444/1008 -f 1/445/1009 426/446/1010 440/444/1011 -f 446/447/1012 441/448/1013 447/449/1014 -f 444/450/1015 443/451/1016 442/452/1017 -f 329/334/1018 326/332/1019 443/451/1020 -f 265/268/1021 329/334/1022 444/450/1023 -f 336/340/1024 444/450/1025 445/453/1026 -f 332/335/1027 264/265/1028 446/447/1029 -f 326/332/1030 332/335/1031 447/449/1032 -f 443/451/1033 447/449/1034 448/454/1035 -f 450/455/1036 449/456/1037 75/457/1038 -f 445/453/1039 442/452/1040 449/456/1041 -f 334/341/1042 445/453/1043 450/455/1044 -f 396/338/1045 450/455/1046 78/458/1047 -f 448/454/1048 441/448/1049 451/262/1050 -f 442/452/1051 448/454/1052 452/261/1053 -f 449/456/1054 452/261/1055 82/459/1056 -f 462/460/1057 453/461/1058 463/462/1059 -f 456/463/1060 455/464/1061 454/465/1062 -f 247/247/1063 240/242/1064 455/464/1065 -f 6/8/1066 247/247/1067 456/463/1068 -f 330/264/1069 456/463/1070 457/466/1071 -f 460/467/1072 459/468/1073 458/469/1074 -f 259/259/1075 256/258/1076 459/468/1077 -f 240/242/1078 259/259/1079 460/467/1080 -f 455/464/1081 460/467/1082 461/470/1083 -f 3/5/1084 462/460/1085 262/260/1086 -f 256/258/1087 262/260/1088 463/462/1089 -f 459/468/1090 463/462/1091 464/471/1092 -f 470/472/1093 469/473/1094 224/474/1095 -f 467/475/1096 466/476/1097 465/477/1098 -f 457/466/1099 454/465/1100 466/476/1101 -f 264/265/1102 457/466/1103 467/475/1104 -f 446/447/1105 467/475/1106 468/478/1107 -f 468/478/1108 465/477/1109 469/473/1110 -f 441/448/1111 468/478/1112 470/472/1113 -f 451/262/1114 470/472/1115 227/479/1116 -f 476/480/1117 471/481/1118 477/482/1119 -f 474/483/1120 473/484/1121 472/485/1122 -f 461/470/1123 458/469/1124 473/484/1125 -f 454/465/1126 461/470/1127 474/483/1128 -f 466/476/1129 474/483/1130 475/486/1131 -f 453/461/1132 476/480/1133 464/471/1134 -f 458/469/1135 464/471/1136 477/482/1137 -f 473/484/1138 477/482/1139 478/487/1140 -f 480/488/1141 479/489/1142 230/490/1143 -f 475/486/1144 472/485/1145 479/489/1146 -f 465/477/1147 475/486/1148 480/488/1149 -f 469/473/1150 480/488/1151 233/491/1152 -f 471/481/1153 481/1/1154 478/487/1155 -f 472/485/1156 478/487/1157 482/3/1158 -f 479/489/1159 482/3/1160 237/492/1161 -f 2/2/1162 237/492/1163 482/3/1164 -f 3/5/1165 262/260/1166 261/6/1167 -f 6/8/1168 222/221/1169 221/9/1170 -f 7/11/1171 84/87/1172 83/12/1173 -f 48/52/1174 14/18/1175 11/13/1176 -f 11/13/1177 46/15/1178 48/52/1179 -f 11/13/1180 14/18/1181 15/21/1182 -f 15/21/1183 13/16/1184 11/13/1185 -f 35/20/1186 18/22/1187 15/21/1188 -f 15/21/1189 14/18/1190 35/20/1191 -f 19/23/1192 17/493/1193 13/16/1194 -f 13/16/1195 15/21/1196 19/23/1197 -f 30/25/1198 22/26/1199 19/23/1200 -f 30/25/1201 19/23/1202 18/22/1203 -f 23/27/1204 21/30/1205 17/493/1206 -f 17/493/1207 19/23/1208 23/27/1209 -f 22/26/1210 27/33/1211 26/28/1212 -f 23/27/1213 26/28/1214 25/29/1215 -f 26/28/1216 24/32/1217 1/31/1218 -f 27/33/1219 20/35/1220 24/32/1221 -f 28/24/1222 32/37/1223 31/34/1224 -f 30/25/1225 31/34/1226 27/33/1227 -f 31/34/1228 29/36/1229 20/35/1230 -f 32/37/1231 16/43/1232 29/36/1233 -f 43/39/1234 36/40/1235 35/20/1236 -f 35/20/1237 33/19/1238 43/39/1239 -f 38/41/1240 28/24/1241 18/22/1242 -f 18/22/1243 35/20/1244 38/41/1245 -f 36/40/1246 40/45/1247 39/42/1248 -f 38/41/1249 39/42/1250 32/37/1251 -f 39/42/1252 37/44/1253 16/43/1254 -f 40/45/1255 34/47/1256 37/44/1257 -f 41/38/1258 45/49/1259 44/46/1260 -f 43/39/1261 44/46/1262 40/45/1263 -f 44/46/1264 42/48/1265 34/47/1266 -f 45/49/1267 12/59/1268 42/48/1269 -f 46/15/1270 62/66/1271 64/50/1272 -f 64/50/1273 48/52/1274 46/15/1275 -f 51/53/1276 33/19/1277 14/18/1278 -f 14/18/1279 48/52/1280 51/53/1281 -f 59/55/1282 52/56/1283 51/53/1284 -f 51/53/1285 49/51/1286 59/55/1287 -f 54/57/1288 41/38/1289 33/19/1290 -f 54/57/1291 33/19/1292 51/53/1293 -f 52/56/1294 56/61/1295 55/58/1296 -f 54/57/1297 55/58/1298 45/49/1299 -f 55/58/1300 53/60/1301 12/59/1302 -f 56/61/1303 50/63/1304 53/60/1305 -f 57/54/1306 61/65/1307 60/62/1308 -f 59/55/1309 60/62/1310 56/61/1311 -f 60/62/1312 58/64/1313 50/63/1314 -f 61/65/1315 47/72/1316 58/64/1317 -f 72/68/1318 65/69/1319 64/50/1320 -f 64/50/1321 62/66/1322 72/68/1323 -f 67/70/1324 57/54/1325 49/51/1326 -f 67/70/1327 49/51/1328 64/50/1329 -f 65/69/1330 69/74/1331 68/71/1332 -f 67/70/1333 68/71/1334 61/65/1335 -f 68/71/1336 66/73/1337 47/72/1338 -f 69/74/1339 63/76/1340 66/73/1341 -f 70/67/1342 74/78/1343 73/75/1344 -f 72/68/1345 73/75/1346 69/74/1347 -f 73/75/1348 71/77/1349 63/76/1350 -f 74/78/1351 8/104/1352 71/77/1353 -f 76/80/1354 80/84/1355 79/81/1356 -f 77/79/1357 79/81/1358 78/82/1359 -f 79/81/1360 11/13/1361 9/17/1362 -f 80/84/1363 10/14/1364 11/13/1365 -f 81/10/1366 83/12/1367 82/85/1368 -f 83/12/1369 77/79/1370 75/83/1371 -f 84/87/1372 76/80/1373 77/79/1374 -f 149/90/1375 85/271/1376 179/270/1377 -f 149/90/1378 179/270/1379 181/88/1380 -f 87/93/1381 119/123/1382 121/126/1383 -f 121/126/1384 90/91/1385 87/93/1386 -f 92/96/1387 46/15/1388 10/14/1389 -f 10/14/1390 90/91/1391 92/96/1392 -f 108/95/1393 93/97/1394 92/96/1395 -f 108/95/1396 92/96/1397 90/91/1398 -f 95/98/1399 62/66/1400 46/15/1401 -f 95/98/1402 46/15/1403 92/96/1404 -f 103/100/1405 96/101/1406 95/98/1407 -f 103/100/1408 95/98/1409 93/97/1410 -f 98/102/1411 70/67/1412 62/66/1413 -f 98/102/1414 62/66/1415 95/98/1416 -f 96/101/1417 100/106/1418 99/103/1419 -f 98/102/1420 99/103/1421 74/78/1422 -f 99/103/1423 97/105/1424 8/104/1425 -f 100/106/1426 94/108/1427 97/105/1428 -f 101/99/1429 105/110/1430 104/107/1431 -f 103/100/1432 104/107/1433 100/106/1434 -f 104/107/1435 102/109/1436 94/108/1437 -f 105/110/1438 91/116/1439 102/109/1440 -f 116/112/1441 109/113/1442 108/95/1443 -f 116/112/1444 108/95/1445 106/94/1446 -f 111/114/1447 101/99/1448 93/97/1449 -f 93/97/1450 108/95/1451 111/114/1452 -f 109/113/1453 113/118/1454 112/115/1455 -f 111/114/1456 112/115/1457 105/110/1458 -f 112/115/1459 110/117/1460 91/116/1461 -f 113/118/1462 107/120/1463 110/117/1464 -f 114/111/1465 118/122/1466 117/119/1467 -f 116/112/1468 117/119/1469 113/118/1470 -f 117/119/1471 115/121/1472 107/120/1473 -f 118/122/1474 88/134/1475 115/121/1476 -f 137/125/1477 122/127/1478 121/126/1479 -f 121/126/1480 119/123/1481 137/125/1482 -f 124/128/1483 106/94/1484 90/91/1485 -f 90/91/1486 121/126/1487 124/128/1488 -f 132/130/1489 125/131/1490 124/128/1491 -f 132/130/1492 124/128/1493 122/127/1494 -f 127/132/1495 114/111/1496 106/94/1497 -f 106/94/1498 124/128/1499 127/132/1500 -f 125/131/1501 129/136/1502 128/133/1503 -f 127/132/1504 128/133/1505 118/122/1506 -f 128/133/1507 126/135/1508 88/134/1509 -f 129/136/1510 123/138/1511 126/135/1512 -f 130/129/1513 134/140/1514 133/137/1515 -f 132/130/1516 133/137/1517 129/136/1518 -f 133/137/1519 131/139/1520 123/138/1521 -f 134/140/1522 120/146/1523 131/139/1524 -f 145/142/1525 138/143/1526 137/125/1527 -f 137/125/1528 135/124/1529 145/142/1530 -f 140/144/1531 130/129/1532 122/127/1533 -f 122/127/1534 137/125/1535 140/144/1536 -f 138/143/1537 142/148/1538 141/145/1539 -f 140/144/1540 141/145/1541 134/140/1542 -f 141/145/1543 139/147/1544 120/146/1545 -f 142/148/1546 136/150/1547 139/147/1548 -f 143/141/1549 147/152/1550 146/149/1551 -f 145/142/1552 146/149/1553 142/148/1554 -f 146/149/1555 144/151/1556 136/150/1557 -f 147/152/1558 86/163/1559 144/151/1560 -f 149/90/1561 150/89/1562 152/155/1563 -f 152/155/1564 119/123/1565 149/90/1566 -f 168/154/1567 153/156/1568 152/155/1569 -f 168/154/1570 152/155/1571 150/89/1572 -f 155/157/1573 135/124/1574 119/123/1575 -f 119/123/1576 152/155/1577 155/157/1578 -f 163/159/1579 156/160/1580 155/157/1581 -f 155/157/1582 153/156/1583 163/159/1584 -f 158/161/1585 143/141/1586 135/124/1587 -f 158/161/1588 135/124/1589 155/157/1590 -f 156/160/1591 160/165/1592 159/162/1593 -f 158/161/1594 159/162/1595 147/152/1596 -f 159/162/1597 157/164/1598 86/163/1599 -f 160/165/1600 154/167/1601 157/164/1602 -f 161/158/1603 165/169/1604 164/166/1605 -f 163/159/1606 164/166/1607 160/165/1608 -f 164/166/1609 162/168/1610 154/167/1611 -f 165/169/1612 151/175/1613 162/168/1614 -f 176/171/1615 169/172/1616 168/154/1617 -f 168/154/1618 166/153/1619 176/171/1620 -f 171/173/1621 161/158/1622 153/156/1623 -f 171/173/1624 153/156/1625 168/154/1626 -f 169/172/1627 173/177/1628 172/174/1629 -f 171/173/1630 172/174/1631 165/169/1632 -f 172/174/1633 170/176/1634 151/175/1635 -f 173/177/1636 167/179/1637 170/176/1638 -f 174/170/1639 178/181/1640 177/178/1641 -f 176/171/1642 177/178/1643 173/177/1644 -f 177/178/1645 175/180/1646 167/179/1647 -f 178/181/1648 148/190/1649 175/180/1650 -f 179/270/1651 195/494/1652 197/182/1653 -f 197/182/1654 181/88/1655 179/270/1656 -f 184/184/1657 166/153/1658 150/89/1659 -f 184/184/1660 150/89/1661 181/88/1662 -f 192/186/1663 185/187/1664 184/184/1665 -f 192/186/1666 184/184/1667 182/183/1668 -f 187/188/1669 174/170/1670 166/153/1671 -f 187/188/1672 166/153/1673 184/184/1674 -f 185/187/1675 189/192/1676 188/189/1677 -f 187/188/1678 188/189/1679 178/181/1680 -f 188/189/1681 186/191/1682 148/190/1683 -f 189/192/1684 183/194/1685 186/191/1686 -f 190/185/1687 194/196/1688 193/193/1689 -f 192/186/1690 193/193/1691 189/192/1692 -f 193/193/1693 191/195/1694 183/194/1695 -f 194/196/1696 180/201/1697 191/195/1698 -f 195/494/1699 203/205/1700 205/197/1701 -f 205/197/1702 197/182/1703 195/494/1704 -f 200/199/1705 190/185/1706 182/183/1707 -f 182/183/1708 197/182/1709 200/199/1710 -f 198/198/1711 202/203/1712 201/200/1713 -f 200/199/1714 201/200/1715 194/196/1716 -f 201/200/1717 199/202/1718 180/201/1719 -f 202/203/1720 196/206/1721 199/202/1722 -f 203/205/1723 207/208/1724 206/204/1725 -f 205/197/1726 206/204/1727 202/203/1728 -f 206/204/1729 204/207/1730 196/206/1731 -f 207/208/1732 4/283/1733 204/207/1734 -f 208/210/1735 215/216/1736 214/211/1737 -f 209/214/1738 212/215/1739 211/212/1740 -f 210/213/1741 211/212/1742 80/84/1743 -f 211/212/1744 89/92/1745 10/14/1746 -f 212/215/1747 87/93/1748 89/92/1749 -f 213/209/1750 214/211/1751 84/87/1752 -f 214/211/1753 210/213/1754 76/80/1755 -f 215/216/1756 209/214/1757 210/213/1758 -f 216/219/1759 219/220/1760 218/217/1761 -f 217/218/1762 218/217/1763 212/215/1764 -f 218/217/1765 149/90/1766 87/93/1767 -f 219/220/1768 85/271/1769 149/90/1770 -f 220/7/1771 221/9/1772 215/216/1773 -f 221/9/1774 217/218/1775 209/214/1776 -f 222/221/1777 216/219/1778 217/218/1779 -f 223/223/1780 239/239/1781 238/224/1782 -f 225/226/1783 229/230/1784 228/227/1785 -f 226/225/1786 228/227/1787 227/228/1788 -f 228/227/1789 81/10/1790 5/86/1791 -f 229/230/1792 7/11/1793 81/10/1794 -f 231/232/1795 235/236/1796 234/233/1797 -f 232/231/1798 234/233/1799 233/234/1800 -f 234/233/1801 226/225/1802 224/229/1803 -f 235/236/1804 225/226/1805 226/225/1806 -f 236/222/1807 238/224/1808 237/237/1809 -f 238/224/1810 232/231/1811 230/235/1812 -f 239/239/1813 231/232/1814 232/231/1815 -f 240/242/1816 247/247/1817 246/240/1818 -f 241/245/1819 244/246/1820 243/243/1821 -f 242/244/1822 243/243/1823 229/230/1824 -f 243/243/1825 213/209/1826 7/11/1827 -f 244/246/1828 208/210/1829 213/209/1830 -f 245/241/1831 246/240/1832 244/246/1833 -f 246/240/1834 220/7/1835 208/210/1836 -f 247/247/1837 6/8/1838 220/7/1839 -f 248/249/1840 255/255/1841 254/250/1842 -f 249/253/1843 252/254/1844 251/251/1845 -f 250/252/1846 251/251/1847 235/236/1848 -f 251/251/1849 242/244/1850 225/226/1851 -f 252/254/1852 241/245/1853 242/244/1854 -f 253/248/1855 254/250/1856 239/239/1857 -f 254/250/1858 250/252/1859 231/232/1860 -f 255/255/1861 249/253/1862 250/252/1863 -f 256/258/1864 259/259/1865 258/256/1866 -f 257/257/1867 258/256/1868 252/254/1869 -f 258/256/1870 245/241/1871 241/245/1872 -f 259/259/1873 240/242/1874 245/241/1875 -f 260/4/1876 261/6/1877 255/255/1878 -f 261/6/1879 257/257/1880 249/253/1881 -f 262/260/1882 256/258/1883 257/257/1884 -f 5/263/1885 82/459/1886 452/261/1887 -f 264/265/1888 332/335/1889 331/266/1890 -f 299/304/1891 268/272/1892 267/267/1893 -f 267/267/1894 297/269/1895 299/304/1896 -f 267/267/1897 268/272/1898 270/275/1899 -f 270/275/1900 179/270/1901 267/267/1902 -f 286/274/1903 271/276/1904 270/275/1905 -f 270/275/1906 268/272/1907 286/274/1908 -f 273/277/1909 195/494/1910 179/270/1911 -f 179/270/1912 270/275/1913 273/277/1914 -f 281/279/1915 274/280/1916 273/277/1917 -f 281/279/1918 273/277/1919 271/276/1920 -f 276/281/1921 203/205/1922 195/494/1923 -f 195/494/1924 273/277/1925 276/281/1926 -f 274/280/1927 278/285/1928 277/282/1929 -f 276/281/1930 277/282/1931 207/208/1932 -f 277/282/1933 275/284/1934 4/283/1935 -f 278/285/1936 272/287/1937 275/284/1938 -f 279/278/1939 283/289/1940 282/286/1941 -f 281/279/1942 282/286/1943 278/285/1944 -f 282/286/1945 280/288/1946 272/287/1947 -f 283/289/1948 269/295/1949 280/288/1950 -f 294/291/1951 287/292/1952 286/274/1953 -f 286/274/1954 284/273/1955 294/291/1956 -f 289/293/1957 279/278/1958 271/276/1959 -f 271/276/1960 286/274/1961 289/293/1962 -f 287/292/1963 291/297/1964 290/294/1965 -f 289/293/1966 290/294/1967 283/289/1968 -f 290/294/1969 288/296/1970 269/295/1971 -f 291/297/1972 285/299/1973 288/296/1974 -f 292/290/1975 296/301/1976 295/298/1977 -f 294/291/1978 295/298/1979 291/297/1980 -f 295/298/1981 293/300/1982 285/299/1983 -f 296/301/1984 266/312/1985 293/300/1986 -f 315/303/1987 300/305/1988 299/304/1989 -f 315/303/1990 299/304/1991 297/269/1992 -f 302/306/1993 284/273/1994 268/272/1995 -f 268/272/1996 299/304/1997 302/306/1998 -f 310/308/1999 303/309/2000 302/306/2001 -f 302/306/2002 300/305/2003 310/308/2004 -f 305/310/2005 292/290/2006 284/273/2007 -f 305/310/2008 284/273/2009 302/306/2010 -f 303/309/2011 307/314/2012 306/311/2013 -f 305/310/2014 306/311/2015 296/301/2016 -f 306/311/2017 304/313/2018 266/312/2019 -f 307/314/2020 301/316/2021 304/313/2022 -f 308/307/2023 312/318/2024 311/315/2025 -f 310/308/2026 311/315/2027 307/314/2028 -f 311/315/2029 309/317/2030 301/316/2031 -f 312/318/2032 298/324/2033 309/317/2034 -f 323/320/2035 316/321/2036 315/303/2037 -f 315/303/2038 313/302/2039 323/320/2040 -f 318/322/2041 308/307/2042 300/305/2043 -f 318/322/2044 300/305/2045 315/303/2046 -f 316/321/2047 320/326/2048 319/323/2049 -f 318/322/2050 319/323/2051 312/318/2052 -f 319/323/2053 317/325/2054 298/324/2055 -f 320/326/2056 314/328/2057 317/325/2058 -f 321/319/2059 325/330/2060 324/327/2061 -f 323/320/2062 324/327/2063 320/326/2064 -f 324/327/2065 322/329/2066 314/328/2067 -f 325/330/2068 263/352/2069 322/329/2070 -f 326/332/2071 329/334/2072 328/333/2073 -f 327/331/2074 328/333/2075 219/220/2076 -f 328/333/2077 267/267/2078 85/271/2079 -f 329/334/2080 265/268/2081 267/267/2082 -f 330/264/2083 331/266/2084 222/221/2085 -f 331/266/2086 327/331/2087 216/219/2088 -f 332/335/2089 326/332/2090 327/331/2091 -f 396/338/2092 9/495/2093 13/431/2094 -f 396/338/2095 13/431/2096 427/336/2097 -f 334/341/2098 366/371/2099 368/374/2100 -f 368/374/2101 337/339/2102 334/341/2103 -f 339/344/2104 297/269/2105 265/268/2106 -f 265/268/2107 337/339/2108 339/344/2109 -f 355/343/2110 340/345/2111 339/344/2112 -f 355/343/2113 339/344/2114 337/339/2115 -f 342/346/2116 313/302/2117 297/269/2118 -f 342/346/2119 297/269/2120 339/344/2121 -f 350/348/2122 343/349/2123 342/346/2124 -f 350/348/2125 342/346/2126 340/345/2127 -f 345/350/2128 321/319/2129 313/302/2130 -f 345/350/2131 313/302/2132 342/346/2133 -f 343/349/2134 347/354/2135 346/351/2136 -f 345/350/2137 346/351/2138 325/330/2139 -f 346/351/2140 344/353/2141 263/352/2142 -f 347/354/2143 341/356/2144 344/353/2145 -f 348/347/2146 352/358/2147 351/355/2148 -f 350/348/2149 351/355/2150 347/354/2151 -f 351/355/2152 349/357/2153 341/356/2154 -f 352/358/2155 338/364/2156 349/357/2157 -f 363/360/2158 356/361/2159 355/343/2160 -f 363/360/2161 355/343/2162 353/342/2163 -f 358/362/2164 348/347/2165 340/345/2166 -f 340/345/2167 355/343/2168 358/362/2169 -f 356/361/2170 360/366/2171 359/363/2172 -f 358/362/2173 359/363/2174 352/358/2175 -f 359/363/2176 357/365/2177 338/364/2178 -f 360/366/2179 354/368/2180 357/365/2181 -f 361/359/2182 365/370/2183 364/367/2184 -f 363/360/2185 364/367/2186 360/366/2187 -f 364/367/2188 362/369/2189 354/368/2190 -f 365/370/2191 335/382/2192 362/369/2193 -f 384/373/2194 369/375/2195 368/374/2196 -f 368/374/2197 366/371/2198 384/373/2199 -f 371/376/2200 353/342/2201 337/339/2202 -f 337/339/2203 368/374/2204 371/376/2205 -f 379/378/2206 372/379/2207 371/376/2208 -f 379/378/2209 371/376/2210 369/375/2211 -f 374/380/2212 361/359/2213 353/342/2214 -f 353/342/2215 371/376/2216 374/380/2217 -f 372/379/2218 376/384/2219 375/381/2220 -f 374/380/2221 375/381/2222 365/370/2223 -f 375/381/2224 373/383/2225 335/382/2226 -f 376/384/2227 370/386/2228 373/383/2229 -f 377/377/2230 381/388/2231 380/385/2232 -f 379/378/2233 380/385/2234 376/384/2235 -f 380/385/2236 378/387/2237 370/386/2238 -f 381/388/2239 367/394/2240 378/387/2241 -f 392/390/2242 385/391/2243 384/373/2244 -f 384/373/2245 382/372/2246 392/390/2247 -f 387/392/2248 377/377/2249 369/375/2250 -f 369/375/2251 384/373/2252 387/392/2253 -f 385/391/2254 389/396/2255 388/393/2256 -f 387/392/2257 388/393/2258 381/388/2259 -f 388/393/2260 386/395/2261 367/394/2262 -f 389/396/2263 383/398/2264 386/395/2265 -f 390/389/2266 394/400/2267 393/397/2268 -f 392/390/2269 393/397/2270 389/396/2271 -f 393/397/2272 391/399/2273 383/398/2274 -f 394/400/2275 333/411/2276 391/399/2277 -f 396/338/2278 397/337/2279 399/403/2280 -f 399/403/2281 366/371/2282 396/338/2283 -f 415/402/2284 400/404/2285 399/403/2286 -f 415/402/2287 399/403/2288 397/337/2289 -f 402/405/2290 382/372/2291 366/371/2292 -f 366/371/2293 399/403/2294 402/405/2295 -f 410/407/2296 403/408/2297 402/405/2298 -f 402/405/2299 400/404/2300 410/407/2301 -f 405/409/2302 390/389/2303 382/372/2304 -f 405/409/2305 382/372/2306 402/405/2307 -f 403/408/2308 407/413/2309 406/410/2310 -f 405/409/2311 406/410/2312 394/400/2313 -f 406/410/2314 404/412/2315 333/411/2316 -f 407/413/2317 401/415/2318 404/412/2319 -f 408/406/2320 412/417/2321 411/414/2322 -f 410/407/2323 411/414/2324 407/413/2325 -f 411/414/2326 409/416/2327 401/415/2328 -f 412/417/2329 398/423/2330 409/416/2331 -f 423/419/2332 416/420/2333 415/402/2334 -f 415/402/2335 413/401/2336 423/419/2337 -f 418/421/2338 408/406/2339 400/404/2340 -f 418/421/2341 400/404/2342 415/402/2343 -f 416/420/2344 420/425/2345 419/422/2346 -f 418/421/2347 419/422/2348 412/417/2349 -f 419/422/2350 417/424/2351 398/423/2352 -f 420/425/2353 414/427/2354 417/424/2355 -f 421/418/2356 425/429/2357 424/426/2358 -f 423/419/2359 424/426/2360 420/425/2361 -f 424/426/2362 422/428/2363 414/427/2364 -f 425/429/2365 395/438/2366 422/428/2367 -f 13/431/2368 17/496/2369 428/430/2370 -f 430/432/2371 413/401/2372 397/337/2373 -f 430/432/2374 397/337/2375 427/336/2376 -f 438/434/2377 431/435/2378 430/432/2379 -f 438/434/2380 430/432/2381 428/430/2382 -f 433/436/2383 421/418/2384 413/401/2385 -f 433/436/2386 413/401/2387 430/432/2388 -f 431/435/2389 435/440/2390 434/437/2391 -f 433/436/2392 434/437/2393 425/429/2394 -f 434/437/2395 432/439/2396 395/438/2397 -f 435/440/2398 429/442/2399 432/439/2400 -f 436/433/2401 440/444/2402 439/441/2403 -f 438/434/2404 439/441/2405 435/440/2406 -f 439/441/2407 437/443/2408 429/442/2409 -f 440/444/2410 426/446/2411 437/443/2412 -f 428/430/2413 17/496/2414 21/497/2415 -f 436/433/2416 428/430/2417 1/445/2418 -f 440/444/2419 436/433/2420 1/445/2421 -f 25/498/2422 1/445/2423 428/430/2424 -f 428/430/2425 21/497/2426 25/498/2427 -f 441/448/2428 448/454/2429 447/449/2430 -f 442/452/2431 445/453/2432 444/450/2433 -f 443/451/2434 444/450/2435 329/334/2436 -f 444/450/2437 336/340/2438 265/268/2439 -f 445/453/2440 334/341/2441 336/340/2442 -f 446/447/2443 447/449/2444 332/335/2445 -f 447/449/2446 443/451/2447 326/332/2448 -f 448/454/2449 442/452/2450 443/451/2451 -f 75/457/2452 78/458/2453 450/455/2454 -f 449/456/2455 450/455/2456 445/453/2457 -f 450/455/2458 396/338/2459 334/341/2460 -f 78/458/2461 9/495/2462 396/338/2463 -f 451/262/2464 452/261/2465 448/454/2466 -f 452/261/2467 449/456/2468 442/452/2469 -f 82/459/2470 75/457/2471 449/456/2472 -f 453/461/2473 464/471/2474 463/462/2475 -f 454/465/2476 457/466/2477 456/463/2478 -f 455/464/2479 456/463/2480 247/247/2481 -f 456/463/2482 330/264/2483 6/8/2484 -f 457/466/2485 264/265/2486 330/264/2487 -f 458/469/2488 461/470/2489 460/467/2490 -f 459/468/2491 460/467/2492 259/259/2493 -f 460/467/2494 455/464/2495 240/242/2496 -f 461/470/2497 454/465/2498 455/464/2499 -f 462/460/2500 463/462/2501 262/260/2502 -f 463/462/2503 459/468/2504 256/258/2505 -f 464/471/2506 458/469/2507 459/468/2508 -f 224/474/2509 227/479/2510 470/472/2511 -f 465/477/2512 468/478/2513 467/475/2514 -f 466/476/2515 467/475/2516 457/466/2517 -f 467/475/2518 446/447/2519 264/265/2520 -f 468/478/2521 441/448/2522 446/447/2523 -f 469/473/2524 470/472/2525 468/478/2526 -f 470/472/2527 451/262/2528 441/448/2529 -f 227/479/2530 5/263/2531 451/262/2532 -f 471/481/2533 478/487/2534 477/482/2535 -f 472/485/2536 475/486/2537 474/483/2538 -f 473/484/2539 474/483/2540 461/470/2541 -f 474/483/2542 466/476/2543 454/465/2544 -f 475/486/2545 465/477/2546 466/476/2547 -f 476/480/2548 477/482/2549 464/471/2550 -f 477/482/2551 473/484/2552 458/469/2553 -f 478/487/2554 472/485/2555 473/484/2556 -f 230/490/2557 233/491/2558 480/488/2559 -f 479/489/2560 480/488/2561 475/486/2562 -f 480/488/2563 469/473/2564 465/477/2565 -f 233/491/2566 224/474/2567 469/473/2568 -f 481/1/2569 482/3/2570 478/487/2571 -f 482/3/2572 479/489/2573 472/485/2574 -f 237/492/2575 230/490/2576 479/489/2577 diff --git a/lamp.obj b/lamp.obj deleted file mode 100644 index 4d0a85c..0000000 --- a/lamp.obj +++ /dev/null @@ -1,1211 +0,0 @@ -# This file uses centimeters as units for non-parametric coordinates. - -mtllib lamp.mtl -g default -v 2.656471 15.855046 5.780191 -v 2.535695 15.855046 5.017639 -v 2.656471 15.855046 4.255087 -v 3.006978 15.855046 3.567179 -v 3.552904 15.855046 3.021253 -v 4.240812 15.855046 2.670746 -v 5.003365 15.855046 2.549970 -v 5.765916 15.855046 2.670746 -v 6.453824 15.855046 3.021253 -v 6.999750 15.855046 3.567179 -v 7.350257 15.855046 4.255087 -v 7.471033 15.855046 5.017639 -v 7.350257 15.855046 5.780191 -v 6.999750 15.855046 6.468100 -v 6.453824 15.855046 7.014026 -v 5.765916 15.855046 7.364532 -v 5.003365 15.855046 7.485309 -v 4.240812 15.855046 7.364532 -v 3.552904 15.855046 7.014026 -v 3.006978 15.855046 6.468100 -v 3.327012 19.818167 5.562319 -v 3.240743 19.818167 5.017639 -v 3.327012 19.818167 4.472960 -v 3.577374 19.818167 3.981596 -v 3.967321 19.818167 3.591650 -v 4.458684 19.818167 3.341287 -v 5.003365 19.818167 3.255018 -v 5.548044 19.818167 3.341287 -v 6.039407 19.818167 3.591650 -v 6.429354 19.818167 3.981596 -v 6.679716 19.818167 4.472960 -v 6.765985 19.818167 5.017639 -v 6.679716 19.818167 5.562319 -v 6.429354 19.818167 6.053682 -v 6.039407 19.818167 6.443629 -v 5.548044 19.818167 6.693992 -v 5.003365 19.818167 6.780261 -v 4.458684 19.818167 6.693992 -v 3.967321 19.818167 6.443629 -v 3.577374 19.818167 6.053682 -v 5.003365 19.818167 5.017639 -v 5.003365 15.855044 5.017639 -v 1.159431 0.014822 6.247877 -v 0.961787 0.014822 5.000000 -v 1.159431 0.014822 3.752123 -v 1.733017 0.014822 2.626398 -v 2.626398 0.014822 1.733017 -v 3.752123 0.014822 1.159431 -v 5.000000 0.014822 0.961787 -v 6.247877 0.014822 1.159431 -v 7.373602 0.014822 1.733017 -v 8.266983 0.014822 2.626398 -v 8.840569 0.014822 3.752123 -v 9.038213 0.014822 5.000000 -v 8.840569 0.014822 6.247877 -v 8.266983 0.014822 7.373602 -v 7.373602 0.014822 8.266983 -v 6.247877 0.014822 8.840569 -v 5.000000 0.014822 9.038213 -v 3.752123 0.014822 8.840569 -v 2.626398 0.014822 8.266983 -v 1.733017 0.014822 7.373602 -v 3.736371 -5.387635 5.410578 -v 3.671342 -5.387635 5.000000 -v 3.736371 -5.387635 4.589422 -v 3.925093 -5.387635 4.219035 -v 4.219035 -5.387635 3.925093 -v 4.589422 -5.387635 3.736371 -v 5.000000 -5.387635 3.671342 -v 5.410578 -5.387635 3.736371 -v 5.780965 -5.387635 3.925093 -v 6.074907 -5.387635 4.219035 -v 6.263629 -5.387635 4.589422 -v 6.328658 -5.387635 5.000000 -v 6.263629 -5.387635 5.410578 -v 6.074907 -5.387635 5.780965 -v 5.780965 -5.387635 6.074907 -v 5.410578 -5.387635 6.263629 -v 5.000000 -5.387635 6.328658 -v 4.589422 -5.387635 6.263629 -v 4.219035 -5.387635 6.074907 -v 3.925093 -5.387635 5.780965 -v 3.780450 -5.669678 5.396256 -v 3.717689 -5.669678 5.000000 -v 3.780450 -5.669678 4.603744 -v 3.962589 -5.669678 4.246277 -v 4.246277 -5.669678 3.962589 -v 4.603744 -5.669678 3.780450 -v 5.000000 -5.669678 3.717689 -v 5.396256 -5.669678 3.780450 -v 5.753723 -5.669678 3.962589 -v 6.037411 -5.669678 4.246277 -v 6.219550 -5.669678 4.603744 -v 6.282311 -5.669678 5.000000 -v 6.219550 -5.669678 5.396256 -v 6.037411 -5.669678 5.753723 -v 5.753723 -5.669678 6.037411 -v 5.396256 -5.669678 6.219550 -v 5.000000 -5.669678 6.282311 -v 4.603744 -5.669678 6.219550 -v 4.246277 -5.669678 6.037411 -v 3.962589 -5.669678 5.753723 -v 1.125356 -11.094143 6.258948 -v 0.925958 -11.094143 5.000000 -v 1.125356 -11.094143 3.741052 -v 1.704031 -11.094143 2.605338 -v 2.605338 -11.094143 1.704031 -v 3.741052 -11.094143 1.125356 -v 5.000000 -11.094143 0.925958 -v 6.258948 -11.094143 1.125356 -v 7.394662 -11.094143 1.704031 -v 8.295969 -11.094143 2.605338 -v 8.874644 -11.094143 3.741052 -v 9.074041 -11.094143 5.000000 -v 8.874644 -11.094143 6.258948 -v 8.295969 -11.094143 7.394662 -v 7.394662 -11.094143 8.295969 -v 6.258948 -11.094143 8.874644 -v 5.000000 -11.094143 9.074041 -v 3.741052 -11.094143 8.874644 -v 2.605338 -11.094143 8.295969 -v 1.704031 -11.094143 7.394662 -v 5.000000 0.014822 5.000000 -v 5.000000 -11.094146 5.000000 -vt 0.000000 -1.000000 -vt 1.000000 -1.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 2.000000 -vt 0.000000 2.000000 -vt 1.000000 3.000000 -vt 0.000000 3.000000 -vt 1.000000 4.000000 -vt 0.000000 4.000000 -vt 1.000000 5.000000 -vt 0.000000 5.000000 -vt 1.000000 6.000000 -vt 0.000000 6.000000 -vt 1.000000 7.000000 -vt 0.000000 7.000000 -vt 1.000000 8.000000 -vt 0.000000 8.000000 -vt 1.000000 9.000000 -vt 0.000000 9.000000 -vt 1.000000 10.000000 -vt 0.000000 10.000000 -vt 1.000000 11.000000 -vt 0.000000 11.000000 -vt 1.000000 12.000000 -vt 0.000000 12.000000 -vt 1.000000 13.000000 -vt 0.000000 13.000000 -vt 1.000000 14.000000 -vt 0.000000 14.000000 -vt 1.000000 15.000000 -vt 0.000000 15.000000 -vt 1.000000 16.000000 -vt 0.000000 16.000000 -vt 1.000000 17.000000 -vt 0.000000 17.000000 -vt 1.000000 18.000000 -vt 0.000000 18.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 -1.000000 -vt 0.000000 0.000000 -vt 0.333333 0.000000 -vt 0.333333 -1.000000 -vt 0.000000 1.000000 -vt 0.333333 1.000000 -vt 0.000000 2.000000 -vt 0.333333 2.000000 -vt 0.000000 3.000000 -vt 0.333333 3.000000 -vt 0.000000 4.000000 -vt 0.333333 4.000000 -vt 0.000000 5.000000 -vt 0.333333 5.000000 -vt 0.000000 6.000000 -vt 0.333333 6.000000 -vt 0.000000 7.000000 -vt 0.333333 7.000000 -vt 0.000000 8.000000 -vt 0.333333 8.000000 -vt 0.000000 9.000000 -vt 0.333333 9.000000 -vt 0.000000 10.000000 -vt 0.333333 10.000000 -vt 0.000000 11.000000 -vt 0.333333 11.000000 -vt 0.000000 12.000000 -vt 0.333333 12.000000 -vt 0.000000 13.000000 -vt 0.333333 13.000000 -vt 0.000000 14.000000 -vt 0.333333 14.000000 -vt 0.000000 15.000000 -vt 0.333333 15.000000 -vt 0.000000 16.000000 -vt 0.333333 16.000000 -vt 0.000000 17.000000 -vt 0.333333 17.000000 -vt 0.000000 18.000000 -vt 0.333333 18.000000 -vt 0.666667 0.000000 -vt 0.666667 -1.000000 -vt 0.666667 1.000000 -vt 0.666667 2.000000 -vt 0.666667 3.000000 -vt 0.666667 4.000000 -vt 0.666667 5.000000 -vt 0.666667 6.000000 -vt 0.666667 7.000000 -vt 0.666667 8.000000 -vt 0.666667 9.000000 -vt 0.666667 10.000000 -vt 0.666667 11.000000 -vt 0.666667 12.000000 -vt 0.666667 13.000000 -vt 0.666667 14.000000 -vt 0.666667 15.000000 -vt 0.666667 16.000000 -vt 0.666667 17.000000 -vt 0.666667 18.000000 -vt 1.000000 0.000000 -vt 1.000000 -1.000000 -vt 1.000000 1.000000 -vt 1.000000 2.000000 -vt 1.000000 3.000000 -vt 1.000000 4.000000 -vt 1.000000 5.000000 -vt 1.000000 6.000000 -vt 1.000000 7.000000 -vt 1.000000 8.000000 -vt 1.000000 9.000000 -vt 1.000000 10.000000 -vt 1.000000 11.000000 -vt 1.000000 12.000000 -vt 1.000000 13.000000 -vt 1.000000 14.000000 -vt 1.000000 15.000000 -vt 1.000000 16.000000 -vt 1.000000 17.000000 -vt 1.000000 18.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.500000 1.000000 -vn -0.972785 0.173061 0.154074 -vn -0.972785 0.173061 0.154074 -vn -0.972785 0.173061 0.154074 -vn -0.972785 0.173061 0.154074 -vn -0.984541 0.175152 0.000000 -vn -0.984541 0.175152 0.000000 -vn -0.936355 0.175152 -0.304240 -vn -0.936355 0.175152 -0.304240 -vn -0.936355 0.175152 -0.304240 -vn -0.936355 0.175152 -0.304240 -vn -0.796511 0.175152 -0.578699 -vn -0.796511 0.175152 -0.578699 -vn -0.796511 0.175152 -0.578699 -vn -0.796511 0.175152 -0.578699 -vn -0.578699 0.175152 -0.796511 -vn -0.578699 0.175152 -0.796511 -vn -0.578699 0.175152 -0.796511 -vn -0.578699 0.175152 -0.796511 -vn -0.304240 0.175152 -0.936355 -vn -0.304240 0.175152 -0.936355 -vn -0.304240 0.175152 -0.936355 -vn -0.304240 0.175152 -0.936355 -vn 0.000000 0.175152 -0.984541 -vn 0.000000 0.175152 -0.984541 -vn 0.000000 0.175152 -0.984541 -vn 0.000000 0.175152 -0.984541 -vn 0.304240 0.175152 -0.936355 -vn 0.304240 0.175152 -0.936355 -vn 0.304240 0.175152 -0.936355 -vn 0.304240 0.175152 -0.936355 -vn 0.578699 0.175152 -0.796511 -vn 0.578699 0.175152 -0.796511 -vn 0.578699 0.175152 -0.796511 -vn 0.578699 0.175152 -0.796511 -vn 0.796511 0.175152 -0.578699 -vn 0.796511 0.175152 -0.578699 -vn 0.796511 0.175152 -0.578699 -vn 0.796511 0.175152 -0.578699 -vn 0.936355 0.175152 -0.304240 -vn 0.936355 0.175152 -0.304240 -vn 0.936355 0.175152 -0.304240 -vn 0.936355 0.175152 -0.304240 -vn 0.984541 0.175152 0.000000 -vn 0.984541 0.175152 0.000000 -vn 0.984541 0.175152 0.000000 -vn 0.984541 0.175152 0.000000 -vn 0.936355 0.175152 0.304240 -vn 0.936355 0.175152 0.304240 -vn 0.936355 0.175152 0.304240 -vn 0.936355 0.175152 0.304240 -vn 0.796511 0.175152 0.578699 -vn 0.796511 0.175152 0.578699 -vn 0.796511 0.175152 0.578699 -vn 0.796511 0.175152 0.578699 -vn 0.578699 0.175152 0.796511 -vn 0.578699 0.175152 0.796511 -vn 0.578699 0.175152 0.796511 -vn 0.578699 0.175152 0.796511 -vn 0.304240 0.175152 0.936355 -vn 0.304240 0.175152 0.936355 -vn 0.304240 0.175152 0.936355 -vn 0.304240 0.175152 0.936355 -vn 0.000000 0.175152 0.984541 -vn 0.000000 0.175152 0.984541 -vn 0.000000 0.175152 0.984541 -vn 0.000000 0.175152 0.984541 -vn -0.304240 0.175152 0.936355 -vn -0.304240 0.175152 0.936355 -vn -0.304240 0.175152 0.936355 -vn -0.304240 0.175152 0.936355 -vn -0.578699 0.175152 0.796511 -vn -0.578699 0.175152 0.796511 -vn -0.578699 0.175152 0.796511 -vn -0.578699 0.175152 0.796511 -vn -0.796511 0.175152 0.578699 -vn -0.796511 0.175152 0.578699 -vn -0.796511 0.175152 0.578699 -vn -0.796511 0.175152 0.578699 -vn -0.936355 0.175152 0.304240 -vn -0.936355 0.175152 0.304240 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 -0.000004 -vn -0.000001 -1.000000 -0.000004 -vn -0.000001 -1.000000 -0.000004 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000000 -1.000000 0.000000 -vn -0.000000 -1.000000 0.000000 -vn -0.000000 -1.000000 0.000000 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 -0.000002 -vn 0.000001 -1.000000 -0.000002 -vn 0.000001 -1.000000 -0.000002 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000004 -vn 0.000001 -1.000000 0.000004 -vn 0.000001 -1.000000 0.000004 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000000 -vn -0.000000 -1.000000 0.000000 -vn -0.000000 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000002 -vn -0.000001 -1.000000 0.000002 -vn -0.000001 -1.000000 0.000002 -vn -0.850126 -0.448316 0.276223 -vn -0.893876 -0.448315 0.000000 -vn -0.896688 -0.442663 0.000000 -vn -0.852801 -0.442663 0.277092 -vn -0.893876 -0.448315 0.000000 -vn -0.850126 -0.448316 -0.276223 -vn -0.852801 -0.442663 -0.277092 -vn -0.896688 -0.442663 0.000000 -vn -0.850126 -0.448316 -0.276223 -vn -0.723160 -0.448316 -0.525407 -vn -0.725436 -0.442663 -0.527060 -vn -0.852801 -0.442663 -0.277092 -vn -0.723160 -0.448316 -0.525407 -vn -0.525407 -0.448316 -0.723160 -vn -0.527060 -0.442663 -0.725436 -vn -0.725436 -0.442663 -0.527060 -vn -0.525407 -0.448316 -0.723160 -vn -0.276223 -0.448316 -0.850126 -vn -0.277092 -0.442663 -0.852801 -vn -0.527060 -0.442663 -0.725436 -vn -0.276223 -0.448316 -0.850126 -vn 0.000000 -0.448316 -0.893875 -vn 0.000000 -0.442663 -0.896688 -vn -0.277092 -0.442663 -0.852801 -vn 0.000000 -0.448316 -0.893875 -vn 0.276223 -0.448316 -0.850126 -vn 0.277092 -0.442663 -0.852801 -vn 0.000000 -0.442663 -0.896688 -vn 0.276223 -0.448316 -0.850126 -vn 0.525407 -0.448316 -0.723160 -vn 0.527060 -0.442663 -0.725436 -vn 0.277092 -0.442663 -0.852801 -vn 0.525407 -0.448316 -0.723160 -vn 0.723160 -0.448316 -0.525407 -vn 0.725436 -0.442663 -0.527060 -vn 0.527060 -0.442663 -0.725436 -vn 0.723160 -0.448316 -0.525407 -vn 0.850126 -0.448316 -0.276223 -vn 0.852801 -0.442663 -0.277092 -vn 0.725436 -0.442663 -0.527060 -vn 0.850126 -0.448316 -0.276223 -vn 0.893876 -0.448315 0.000000 -vn 0.896688 -0.442663 0.000000 -vn 0.852801 -0.442663 -0.277092 -vn 0.893876 -0.448315 0.000000 -vn 0.850126 -0.448316 0.276223 -vn 0.852801 -0.442663 0.277092 -vn 0.896688 -0.442663 0.000000 -vn 0.850126 -0.448316 0.276223 -vn 0.723160 -0.448316 0.525407 -vn 0.725436 -0.442663 0.527060 -vn 0.852801 -0.442663 0.277092 -vn 0.723160 -0.448316 0.525407 -vn 0.525407 -0.448316 0.723160 -vn 0.527060 -0.442663 0.725436 -vn 0.725436 -0.442663 0.527060 -vn 0.525407 -0.448316 0.723160 -vn 0.276223 -0.448316 0.850126 -vn 0.277092 -0.442663 0.852801 -vn 0.527060 -0.442663 0.725436 -vn 0.276223 -0.448316 0.850126 -vn 0.000000 -0.448316 0.893875 -vn 0.000000 -0.442663 0.896688 -vn 0.277092 -0.442663 0.852801 -vn 0.000000 -0.448316 0.893875 -vn -0.276223 -0.448316 0.850126 -vn -0.277092 -0.442663 0.852801 -vn 0.000000 -0.442663 0.896688 -vn -0.276223 -0.448316 0.850126 -vn -0.525407 -0.448316 0.723160 -vn -0.527060 -0.442663 0.725436 -vn -0.277092 -0.442663 0.852801 -vn -0.525407 -0.448316 0.723160 -vn -0.723160 -0.448316 0.525407 -vn -0.725436 -0.442663 0.527060 -vn -0.527060 -0.442663 0.725436 -vn -0.723160 -0.448316 0.525407 -vn -0.850126 -0.448316 0.276223 -vn -0.852801 -0.442663 0.277092 -vn -0.725436 -0.442663 0.527060 -vn -0.852801 -0.442663 0.277092 -vn -0.896688 -0.442663 0.000000 -vn -0.895023 0.446020 0.000000 -vn -0.851218 0.446020 0.276577 -vn -0.896688 -0.442663 0.000000 -vn -0.852801 -0.442663 -0.277092 -vn -0.851218 0.446020 -0.276577 -vn -0.895023 0.446020 0.000000 -vn -0.852801 -0.442663 -0.277092 -vn -0.725436 -0.442663 -0.527060 -vn -0.724089 0.446020 -0.526081 -vn -0.851218 0.446020 -0.276577 -vn -0.725436 -0.442663 -0.527060 -vn -0.527060 -0.442663 -0.725436 -vn -0.526081 0.446020 -0.724089 -vn -0.724089 0.446020 -0.526081 -vn -0.527060 -0.442663 -0.725436 -vn -0.277092 -0.442663 -0.852801 -vn -0.276577 0.446020 -0.851218 -vn -0.526081 0.446020 -0.724089 -vn -0.277092 -0.442663 -0.852801 -vn 0.000000 -0.442663 -0.896688 -vn 0.000000 0.446020 -0.895023 -vn -0.276577 0.446020 -0.851218 -vn 0.000000 -0.442663 -0.896688 -vn 0.277092 -0.442663 -0.852801 -vn 0.276577 0.446020 -0.851218 -vn 0.000000 0.446020 -0.895023 -vn 0.277092 -0.442663 -0.852801 -vn 0.527060 -0.442663 -0.725436 -vn 0.526081 0.446020 -0.724089 -vn 0.276577 0.446020 -0.851218 -vn 0.527060 -0.442663 -0.725436 -vn 0.725436 -0.442663 -0.527060 -vn 0.724089 0.446020 -0.526081 -vn 0.526081 0.446020 -0.724089 -vn 0.725436 -0.442663 -0.527060 -vn 0.852801 -0.442663 -0.277092 -vn 0.851218 0.446020 -0.276577 -vn 0.724089 0.446020 -0.526081 -vn 0.852801 -0.442663 -0.277092 -vn 0.896688 -0.442663 0.000000 -vn 0.895023 0.446020 0.000000 -vn 0.851218 0.446020 -0.276577 -vn 0.896688 -0.442663 0.000000 -vn 0.852801 -0.442663 0.277092 -vn 0.851218 0.446020 0.276577 -vn 0.895023 0.446020 0.000000 -vn 0.852801 -0.442663 0.277092 -vn 0.725436 -0.442663 0.527060 -vn 0.724089 0.446020 0.526081 -vn 0.851218 0.446020 0.276577 -vn 0.725436 -0.442663 0.527060 -vn 0.527060 -0.442663 0.725436 -vn 0.526081 0.446020 0.724089 -vn 0.724089 0.446020 0.526081 -vn 0.527060 -0.442663 0.725436 -vn 0.277092 -0.442663 0.852801 -vn 0.276577 0.446020 0.851218 -vn 0.526081 0.446020 0.724089 -vn 0.277092 -0.442663 0.852801 -vn 0.000000 -0.442663 0.896688 -vn 0.000000 0.446020 0.895023 -vn 0.276577 0.446020 0.851218 -vn 0.000000 -0.442663 0.896688 -vn -0.277092 -0.442663 0.852801 -vn -0.276577 0.446020 0.851218 -vn 0.000000 0.446020 0.895023 -vn -0.277092 -0.442663 0.852801 -vn -0.527060 -0.442663 0.725436 -vn -0.526081 0.446020 0.724089 -vn -0.276577 0.446020 0.851218 -vn -0.527060 -0.442663 0.725436 -vn -0.725436 -0.442663 0.527060 -vn -0.724089 0.446020 0.526081 -vn -0.526081 0.446020 0.724089 -vn -0.725436 -0.442663 0.527060 -vn -0.852801 -0.442663 0.277092 -vn -0.851218 0.446020 0.276577 -vn -0.724089 0.446020 0.526081 -vn -0.851218 0.446020 0.276577 -vn -0.895023 0.446020 0.000000 -vn -0.889154 0.457608 0.000000 -vn -0.845636 0.457608 0.274764 -vn -0.895023 0.446020 0.000000 -vn -0.851218 0.446020 -0.276577 -vn -0.845636 0.457608 -0.274764 -vn -0.889154 0.457608 0.000000 -vn -0.851218 0.446020 -0.276577 -vn -0.724089 0.446020 -0.526081 -vn -0.719341 0.457608 -0.522631 -vn -0.845636 0.457608 -0.274764 -vn -0.724089 0.446020 -0.526081 -vn -0.526081 0.446020 -0.724089 -vn -0.522632 0.457608 -0.719341 -vn -0.719341 0.457608 -0.522631 -vn -0.526081 0.446020 -0.724089 -vn -0.276577 0.446020 -0.851218 -vn -0.274764 0.457608 -0.845636 -vn -0.522632 0.457608 -0.719341 -vn -0.276577 0.446020 -0.851218 -vn 0.000000 0.446020 -0.895023 -vn 0.000000 0.457608 -0.889154 -vn -0.274764 0.457608 -0.845636 -vn 0.000000 0.446020 -0.895023 -vn 0.276577 0.446020 -0.851218 -vn 0.274764 0.457608 -0.845636 -vn 0.000000 0.457608 -0.889154 -vn 0.276577 0.446020 -0.851218 -vn 0.526081 0.446020 -0.724089 -vn 0.522632 0.457608 -0.719341 -vn 0.274764 0.457608 -0.845636 -vn 0.526081 0.446020 -0.724089 -vn 0.724089 0.446020 -0.526081 -vn 0.719341 0.457608 -0.522631 -vn 0.522632 0.457608 -0.719341 -vn 0.724089 0.446020 -0.526081 -vn 0.851218 0.446020 -0.276577 -vn 0.845636 0.457608 -0.274764 -vn 0.719341 0.457608 -0.522631 -vn 0.851218 0.446020 -0.276577 -vn 0.895023 0.446020 0.000000 -vn 0.889154 0.457608 0.000000 -vn 0.845636 0.457608 -0.274764 -vn 0.895023 0.446020 0.000000 -vn 0.851218 0.446020 0.276577 -vn 0.845636 0.457608 0.274764 -vn 0.889154 0.457608 0.000000 -vn 0.851218 0.446020 0.276577 -vn 0.724089 0.446020 0.526081 -vn 0.719341 0.457608 0.522631 -vn 0.845636 0.457608 0.274764 -vn 0.724089 0.446020 0.526081 -vn 0.526081 0.446020 0.724089 -vn 0.522632 0.457608 0.719341 -vn 0.719341 0.457608 0.522631 -vn 0.526081 0.446020 0.724089 -vn 0.276577 0.446020 0.851218 -vn 0.274764 0.457608 0.845636 -vn 0.522632 0.457608 0.719341 -vn 0.276577 0.446020 0.851218 -vn 0.000000 0.446020 0.895023 -vn 0.000000 0.457608 0.889154 -vn 0.274764 0.457608 0.845636 -vn 0.000000 0.446020 0.895023 -vn -0.276577 0.446020 0.851218 -vn -0.274764 0.457608 0.845636 -vn 0.000000 0.457608 0.889154 -vn -0.276577 0.446020 0.851218 -vn -0.526081 0.446020 0.724089 -vn -0.522632 0.457608 0.719341 -vn -0.274764 0.457608 0.845636 -vn -0.526081 0.446020 0.724089 -vn -0.724089 0.446020 0.526081 -vn -0.719341 0.457608 0.522631 -vn -0.522632 0.457608 0.719341 -vn -0.724089 0.446020 0.526081 -vn -0.851218 0.446020 0.276577 -vn -0.845636 0.457608 0.274764 -vn -0.719341 0.457608 0.522631 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn -0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 -0.000001 -vn -0.000001 -1.000000 -0.000001 -vn -0.000001 -1.000000 -0.000001 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn -0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000000 -1.000000 -0.000001 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 -0.000001 -vn 0.000001 -1.000000 -0.000001 -vn 0.000001 -1.000000 -0.000001 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000001 -vn 0.000001 -1.000000 0.000001 -vn 0.000001 -1.000000 0.000001 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000001 -1.000000 0.000000 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn 0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000000 -1.000000 0.000001 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000000 -vn -0.000001 -1.000000 0.000001 -vn -0.000001 -1.000000 0.000001 -vn -0.000001 -1.000000 0.000001 -s off -g polySurface1 -usemtl initialShadingGroup -f 1/1/1 21/2/2 22/3/3 2/4/4 -f 2/4/5 22/3/6 23/5/7 3/6/8 -f 3/6/9 23/5/10 24/7/11 4/8/12 -f 4/8/13 24/7/14 25/9/15 5/10/16 -f 5/10/17 25/9/18 26/11/19 6/12/20 -f 6/12/21 26/11/22 27/13/23 7/14/24 -f 7/14/25 27/13/26 28/15/27 8/16/28 -f 8/16/29 28/15/30 29/17/31 9/18/32 -f 9/18/33 29/17/34 30/19/35 10/20/36 -f 10/20/37 30/19/38 31/21/39 11/22/40 -f 11/22/41 31/21/42 32/23/43 12/24/44 -f 12/24/45 32/23/46 33/25/47 13/26/48 -f 13/26/49 33/25/50 34/27/51 14/28/52 -f 14/28/53 34/27/54 35/29/55 15/30/56 -f 15/30/57 35/29/58 36/31/59 16/32/60 -f 16/32/61 36/31/62 37/33/63 17/34/64 -f 17/34/65 37/33/66 38/35/67 18/36/68 -f 18/36/69 38/35/70 39/37/71 19/38/72 -f 19/38/73 39/37/74 40/39/75 20/40/76 -f 20/40/77 40/39/78 21/2/79 1/1/80 -f 22/41/81 21/42/82 41/43/83 -f 23/44/84 22/45/85 41/46/86 -f 24/47/87 23/48/88 41/49/89 -f 25/50/90 24/51/91 41/52/92 -f 26/53/93 25/54/94 41/55/95 -f 27/56/96 26/57/97 41/58/98 -f 28/59/99 27/60/100 41/61/101 -f 29/62/102 28/63/103 41/64/104 -f 30/65/105 29/66/106 41/67/107 -f 31/68/108 30/69/109 41/70/110 -f 32/71/111 31/72/112 41/73/113 -f 33/74/114 32/75/115 41/76/116 -f 34/77/117 33/78/118 41/79/119 -f 35/80/120 34/81/121 41/82/122 -f 36/83/123 35/84/124 41/85/125 -f 37/86/126 36/87/127 41/88/128 -f 38/89/129 37/90/130 41/91/131 -f 39/92/132 38/93/133 41/94/134 -f 40/95/135 39/96/136 41/97/137 -f 21/98/138 40/99/139 41/100/140 -f 1/101/141 2/102/142 42/103/143 -f 2/104/144 3/105/145 42/106/146 -f 3/107/147 4/108/148 42/109/149 -f 4/110/150 5/111/151 42/112/152 -f 5/113/153 6/114/154 42/115/155 -f 6/116/156 7/117/157 42/118/158 -f 7/119/159 8/120/160 42/121/161 -f 8/122/162 9/123/163 42/124/164 -f 9/125/165 10/126/166 42/127/167 -f 10/128/168 11/129/169 42/130/170 -f 11/131/171 12/132/172 42/133/173 -f 12/134/174 13/135/175 42/136/176 -f 13/137/177 14/138/178 42/139/179 -f 14/140/180 15/141/181 42/142/182 -f 15/143/183 16/144/184 42/145/185 -f 16/146/186 17/147/187 42/148/188 -f 17/149/189 18/150/190 42/151/191 -f 18/152/192 19/153/193 42/154/194 -f 19/155/195 20/156/196 42/157/197 -f 20/158/198 1/159/199 42/160/200 -f 43/161/201 44/162/202 64/163/203 63/164/204 -f 44/162/205 45/165/206 65/166/207 64/163/208 -f 45/165/209 46/167/210 66/168/211 65/166/212 -f 46/167/213 47/169/214 67/170/215 66/168/216 -f 47/169/217 48/171/218 68/172/219 67/170/220 -f 48/171/221 49/173/222 69/174/223 68/172/224 -f 49/173/225 50/175/226 70/176/227 69/174/228 -f 50/175/229 51/177/230 71/178/231 70/176/232 -f 51/177/233 52/179/234 72/180/235 71/178/236 -f 52/179/237 53/181/238 73/182/239 72/180/240 -f 53/181/241 54/183/242 74/184/243 73/182/244 -f 54/183/245 55/185/246 75/186/247 74/184/248 -f 55/185/249 56/187/250 76/188/251 75/186/252 -f 56/187/253 57/189/254 77/190/255 76/188/256 -f 57/189/257 58/191/258 78/192/259 77/190/260 -f 58/191/261 59/193/262 79/194/263 78/192/264 -f 59/193/265 60/195/266 80/196/267 79/194/268 -f 60/195/269 61/197/270 81/198/271 80/196/272 -f 61/197/273 62/199/274 82/200/275 81/198/276 -f 62/199/277 43/161/278 63/164/279 82/200/280 -f 63/164/281 64/163/282 84/201/283 83/202/284 -f 64/163/285 65/166/286 85/203/287 84/201/288 -f 65/166/289 66/168/290 86/204/291 85/203/292 -f 66/168/293 67/170/294 87/205/295 86/204/296 -f 67/170/297 68/172/298 88/206/299 87/205/300 -f 68/172/301 69/174/302 89/207/303 88/206/304 -f 69/174/305 70/176/306 90/208/307 89/207/308 -f 70/176/309 71/178/310 91/209/311 90/208/312 -f 71/178/313 72/180/314 92/210/315 91/209/316 -f 72/180/317 73/182/318 93/211/319 92/210/320 -f 73/182/321 74/184/322 94/212/323 93/211/324 -f 74/184/325 75/186/326 95/213/327 94/212/328 -f 75/186/329 76/188/330 96/214/331 95/213/332 -f 76/188/333 77/190/334 97/215/335 96/214/336 -f 77/190/337 78/192/338 98/216/339 97/215/340 -f 78/192/341 79/194/342 99/217/343 98/216/344 -f 79/194/345 80/196/346 100/218/347 99/217/348 -f 80/196/349 81/198/350 101/219/351 100/218/352 -f 81/198/353 82/200/354 102/220/355 101/219/356 -f 82/200/357 63/164/358 83/202/359 102/220/360 -f 83/202/361 84/201/362 104/221/363 103/222/364 -f 84/201/365 85/203/366 105/223/367 104/221/368 -f 85/203/369 86/204/370 106/224/371 105/223/372 -f 86/204/373 87/205/374 107/225/375 106/224/376 -f 87/205/377 88/206/378 108/226/379 107/225/380 -f 88/206/381 89/207/382 109/227/383 108/226/384 -f 89/207/385 90/208/386 110/228/387 109/227/388 -f 90/208/389 91/209/390 111/229/391 110/228/392 -f 91/209/393 92/210/394 112/230/395 111/229/396 -f 92/210/397 93/211/398 113/231/399 112/230/400 -f 93/211/401 94/212/402 114/232/403 113/231/404 -f 94/212/405 95/213/406 115/233/407 114/232/408 -f 95/213/409 96/214/410 116/234/411 115/233/412 -f 96/214/413 97/215/414 117/235/415 116/234/416 -f 97/215/417 98/216/418 118/236/419 117/235/420 -f 98/216/421 99/217/422 119/237/423 118/236/424 -f 99/217/425 100/218/426 120/238/427 119/237/428 -f 100/218/429 101/219/430 121/239/431 120/238/432 -f 101/219/433 102/220/434 122/240/435 121/239/436 -f 102/220/437 83/202/438 103/222/439 122/240/440 -f 44/241/441 43/242/442 123/243/443 -f 45/244/444 44/245/445 123/246/446 -f 46/247/447 45/248/448 123/249/449 -f 47/250/450 46/251/451 123/252/452 -f 48/253/453 47/254/454 123/255/455 -f 49/256/456 48/257/457 123/258/458 -f 50/259/459 49/260/460 123/261/461 -f 51/262/462 50/263/463 123/264/464 -f 52/265/465 51/266/466 123/267/467 -f 53/268/468 52/269/469 123/270/470 -f 54/271/471 53/272/472 123/273/473 -f 55/274/474 54/275/475 123/276/476 -f 56/277/477 55/278/478 123/279/479 -f 57/280/480 56/281/481 123/282/482 -f 58/283/483 57/284/484 123/285/485 -f 59/286/486 58/287/487 123/288/488 -f 60/289/489 59/290/490 123/291/491 -f 61/292/492 60/293/493 123/294/494 -f 62/295/495 61/296/496 123/297/497 -f 43/298/498 62/299/499 123/300/500 -f 103/301/501 104/302/502 124/303/503 -f 104/304/504 105/305/505 124/306/506 -f 105/307/507 106/308/508 124/309/509 -f 106/310/510 107/311/511 124/312/512 -f 107/313/513 108/314/514 124/315/515 -f 108/316/516 109/317/517 124/318/518 -f 109/319/519 110/320/520 124/321/521 -f 110/322/522 111/323/523 124/324/524 -f 111/325/525 112/326/526 124/327/527 -f 112/328/528 113/329/529 124/330/530 -f 113/331/531 114/332/532 124/333/533 -f 114/334/534 115/335/535 124/336/536 -f 115/337/537 116/338/538 124/339/539 -f 116/340/540 117/341/541 124/342/542 -f 117/343/543 118/344/544 124/345/545 -f 118/346/546 119/347/547 124/348/548 -f 119/349/549 120/350/550 124/351/551 -f 120/352/552 121/353/553 124/354/554 -f 121/355/555 122/356/556 124/357/557 -f 122/358/558 103/359/559 124/360/560 diff --git a/src/main.js b/src/main.js index 039f69c..208533d 100644 --- a/src/main.js +++ b/src/main.js @@ -19,7 +19,7 @@ const DEFAULT_GRID_RES = 30; const DEFAULT_GRID_WIDTH = 6; const DEFAULT_GRID_HEIGHT = 17; const DEFAULT_GRID_DEPTH = 6; -const DEFAULT_NUM_METABALLS = 10; +const DEFAULT_NUM_METABALLS = 7; const DEFAULT_MIN_RADIUS = 0.5; const DEFAULT_MAX_RADIUS = 1; const DEFAULT_MAX_SPEEDX = 0.005; @@ -124,7 +124,7 @@ function onLoad(framework) { //scene.add(new THREE.AxisHelper(20)); var objLoader = new THREE.OBJLoader(); - var obj = objLoader.load('glass.obj', function(obj) { + var obj = objLoader.load(require('./assets/glass.obj'), function(obj) { glassGeo = obj.children[0].geometry; var glass = new THREE.Mesh(glassGeo, GLASS_MAT); glass.translateX(-1.5); @@ -133,7 +133,7 @@ function onLoad(framework) { loaded = true; }); - var obj = objLoader.load('lamp.obj', function(obj) { + var obj = objLoader.load(require('./assets/lamp.obj'), function(obj) { lampGeo = obj.children[0].geometry; var lamp = new THREE.Mesh(lampGeo, METAL_MAT); lamp.translateX(-1.5); From 3f3919183965af59393ff6b09980b6fa575e9fd5 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Mon, 27 Feb 2017 21:04:03 -0500 Subject: [PATCH 11/14] gui --- src/framework.js | 3 +- src/main.js | 71 +++++++++++++++++++------------------------ src/marching_cubes.js | 7 ++++- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/framework.js b/src/framework.js index 37880d0..9912747 100644 --- a/src/framework.js +++ b/src/framework.js @@ -14,8 +14,7 @@ function init(callback, update) { stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); - var gui = new DAT.GUI({autoPlace: false}); - + var gui = new DAT.GUI(); var framework = { gui: gui, diff --git a/src/main.js b/src/main.js index 208533d..0885ac8 100644 --- a/src/main.js +++ b/src/main.js @@ -23,7 +23,7 @@ const DEFAULT_NUM_METABALLS = 7; const DEFAULT_MIN_RADIUS = 0.5; const DEFAULT_MAX_RADIUS = 1; const DEFAULT_MAX_SPEEDX = 0.005; -const DEFAULT_MAX_SPEEDY = 0.03; +const DEFAULT_MAX_SPEEDY = 0.3; var options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'}; var loaded = false; @@ -191,46 +191,37 @@ function setupGUI(gui) { // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage + gui.add(App.config, 'numMetaballs', 1, 10).step(1).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + + gui.add(App.config, 'minRadius', 0, 1).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + + gui.add(App.config, 'maxRadius', 1, 2).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + + gui.add(App.config, 'maxSpeedY', 0, 1).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + + gui.add(App.config, 'isolevel', 0, 2).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + + gui.add(App.config, 'gridRes', 1, 40).step(1).onChange(function(value) { + App.marchingCubes.reset(); + App.marchingCubes = new MarchingCubes(App); + }); + - // gui.add(App, 'isPaused').onChange(function(value) { - // App.isPaused = value; - // if (value) { - // App.marchingCubes.pause(); - // } else { - // App.marchingCubes.play(); - // } - // }); - - // gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) { - // App.config.numMetaballs = value; - // App.marchingCubes.init(App); - // }); - - // --- DEBUG --- - - // var debugFolder = gui.addFolder('Debug'); - // debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) { - // App.marchingCubes.showGrid = value; - // if (value) { - // App.marchingCubes.show(); - // } else { - // App.marchingCubes.hide(); - // } - // }); - - // debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) { - // App.marchingCubes.showSpheres = value; - // if (value) { - // for (var i = 0; i < App.config.numMetaballs; i++) { - // App.marchingCubes.balls[i].show(); - // } - // } else { - // for (var i = 0; i < App.config.numMetaballs; i++) { - // App.marchingCubes.balls[i].hide(); - // } - // } - // }); - // debugFolder.open(); } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate diff --git a/src/marching_cubes.js b/src/marching_cubes.js index 93841f7..2a51e3b 100644 --- a/src/marching_cubes.js +++ b/src/marching_cubes.js @@ -103,6 +103,11 @@ export default class MarchingCubes { this.makeMesh(); }; + reset() { + this.scene.remove(this.mesh); + this.balls = []; balls = []; + }; + // Convert from 1D index to 3D indices i1toi3(i1) { @@ -166,7 +171,7 @@ export default class MarchingCubes { pos = new THREE.Vector3(3, 3, 3); vx = 0 - vy = (Math.random() * 2 - 1) * this.maxSpeedY; + vy = (Math.random() * 2 - 1) * this.maxSpeedY/10; vz = 0 vel = new THREE.Vector3(vx, vy, vz); From aa953f78fef18128e563c0c4e4376a0a84095265 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Mon, 27 Feb 2017 21:05:42 -0500 Subject: [PATCH 12/14] deploy --- build/assets/glass-5b14a7.obj | 4423 +++++++++++++++++++++++++++++++++ build/assets/glass.mtl | 6 + build/assets/lamp-1bcc16.obj | 1211 +++++++++ build/assets/lamp.mtl | 6 + build/bundle.js | 107 +- build/bundle.js.map | 2 +- src/assets/glass.obj | 4423 +++++++++++++++++++++++++++++++++ src/assets/lamp.obj | 1211 +++++++++ 8 files changed, 11338 insertions(+), 51 deletions(-) create mode 100644 build/assets/glass-5b14a7.obj create mode 100644 build/assets/glass.mtl create mode 100644 build/assets/lamp-1bcc16.obj create mode 100644 build/assets/lamp.mtl create mode 100644 src/assets/glass.obj create mode 100644 src/assets/lamp.obj diff --git a/build/assets/glass-5b14a7.obj b/build/assets/glass-5b14a7.obj new file mode 100644 index 0000000..11a96f9 --- /dev/null +++ b/build/assets/glass-5b14a7.obj @@ -0,0 +1,4423 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib glass.mtl +g default +v 1.034828 0.023645 5.000000 +v 2.478410 15.929955 5.000000 +v 7.521590 15.929955 5.000000 +v 8.965172 0.023645 5.000000 +v 1.417236 7.928881 5.000000 +v 8.582764 7.928881 5.000000 +v 3.208639 7.928881 1.897309 +v 3.017437 0.023645 1.566141 +v 0.875664 2.621381 5.000000 +v 2.937856 2.621381 1.428304 +v 1.428295 2.621381 2.937872 +v 1.566132 0.023645 3.017453 +v 0.821208 0.615620 5.000000 +v 1.381136 0.615620 2.910645 +v 0.963631 0.615620 3.918452 +v 1.169970 0.023645 3.973740 +v 0.894509 0.142910 5.000000 +v 1.034433 0.142910 3.937423 +v 0.929731 0.142910 4.464145 +v 1.068846 0.023645 4.482460 +v 0.956291 0.039097 5.000000 +v 0.990983 0.039097 4.472209 +v 0.964993 0.039097 4.735543 +v 1.043362 0.023645 4.740679 +v 0.993465 0.020326 5.000000 +v 1.002088 0.020326 4.737974 +v 1.027838 0.020326 4.477061 +v 1.094110 0.039097 3.953414 +v 1.111107 0.023645 4.226447 +v 1.034081 0.039097 4.211125 +v 1.070540 0.020326 4.218377 +v 1.130017 0.020326 3.963035 +v 1.444614 0.142910 2.947294 +v 1.336707 0.023645 3.482630 +v 1.207070 0.142910 3.428933 +v 1.264149 0.039097 3.452576 +v 1.245260 0.023645 3.725444 +v 1.170891 0.039097 3.700200 +v 1.206092 0.020326 3.712149 +v 1.298493 0.020326 3.466802 +v 1.498118 0.039097 2.978185 +v 1.443833 0.023645 3.246301 +v 1.373397 0.039097 3.211566 +v 1.406737 0.020326 3.228007 +v 1.530311 0.020326 2.996772 +v 2.910628 0.615620 1.381145 +v 2.196266 0.023645 2.196279 +v 2.045218 0.615620 2.045232 +v 2.097048 0.142910 2.097061 +v 1.854217 0.023645 2.586172 +v 1.742894 0.142910 2.500752 +v 1.791910 0.039097 2.538362 +v 1.703097 0.023645 2.797079 +v 1.637796 0.039097 2.753446 +v 1.668705 0.020326 2.774099 +v 1.821402 0.020326 2.560992 +v 2.140734 0.039097 2.140747 +v 2.018867 0.023645 2.385640 +v 1.959821 0.039097 2.333858 +v 1.987769 0.020326 2.358368 +v 2.167019 0.020326 2.167032 +v 2.947278 0.142910 1.444624 +v 2.586158 0.023645 1.854228 +v 2.500737 0.142910 1.742906 +v 2.538347 0.039097 1.791921 +v 2.385627 0.023645 2.018879 +v 2.333844 0.039097 1.959833 +v 2.358355 0.020326 1.987781 +v 2.560978 0.020326 1.821413 +v 2.978169 0.039097 1.498128 +v 2.797064 0.023645 1.703107 +v 2.753431 0.039097 1.637806 +v 2.774084 0.020326 1.668715 +v 2.996756 0.020326 1.530321 +v 1.117453 5.293516 5.000000 +v 3.058749 5.293516 1.637695 +v 1.637686 5.293516 3.058764 +v 0.974417 3.840676 5.000000 +v 1.513815 3.840676 2.987248 +v 2.987231 3.840676 1.513825 +v 1.897300 7.928881 3.208653 +v 1.254732 6.544681 5.000000 +v 1.756570 6.544681 3.127403 +v 3.127388 6.544681 1.756579 +v 9.124336 2.621381 5.000000 +v 6.982563 0.023645 1.566141 +v 7.062144 2.621381 1.428304 +v 5.000000 0.023645 1.034828 +v 5.000000 2.621381 0.875664 +v 5.000000 0.615620 0.821208 +v 3.973732 0.023645 1.169972 +v 3.918442 0.615620 0.963634 +v 3.937414 0.142910 1.034436 +v 3.482617 0.023645 1.336712 +v 3.428920 0.142910 1.207076 +v 3.452563 0.039097 1.264154 +v 3.246287 0.023645 1.443840 +v 3.211552 0.039097 1.373404 +v 3.227993 0.020326 1.406744 +v 3.466789 0.020326 1.298498 +v 3.953405 0.039097 1.094112 +v 3.725433 0.023645 1.245263 +v 3.700189 0.039097 1.170894 +v 3.712138 0.020326 1.206095 +v 3.963026 0.020326 1.130019 +v 5.000000 0.142910 0.894509 +v 4.482456 0.023645 1.068847 +v 4.464141 0.142910 0.929731 +v 4.472205 0.039097 0.990984 +v 4.226440 0.023645 1.111109 +v 4.211118 0.039097 1.034083 +v 4.218370 0.020326 1.070542 +v 4.477057 0.020326 1.027839 +v 5.000000 0.039097 0.956291 +v 4.740677 0.023645 1.043362 +v 4.735540 0.039097 0.964994 +v 4.737971 0.020326 1.002088 +v 5.000000 0.020326 0.993465 +v 7.089372 0.615620 1.381145 +v 6.026268 0.023645 1.169972 +v 6.081558 0.615620 0.963634 +v 6.062586 0.142910 1.034436 +v 5.517544 0.023645 1.068847 +v 5.535859 0.142910 0.929731 +v 5.527795 0.039097 0.990984 +v 5.259323 0.023645 1.043362 +v 5.264460 0.039097 0.964994 +v 5.262029 0.020326 1.002088 +v 5.522943 0.020326 1.027839 +v 6.046595 0.039097 1.094112 +v 5.773560 0.023645 1.111109 +v 5.788882 0.039097 1.034083 +v 5.781630 0.020326 1.070542 +v 6.036974 0.020326 1.130019 +v 7.052722 0.142910 1.444624 +v 6.517383 0.023645 1.336712 +v 6.571080 0.142910 1.207076 +v 6.547437 0.039097 1.264154 +v 6.274567 0.023645 1.245263 +v 6.299811 0.039097 1.170894 +v 6.287862 0.020326 1.206095 +v 6.533211 0.020326 1.298498 +v 7.021831 0.039097 1.498128 +v 6.753713 0.023645 1.443840 +v 6.788448 0.039097 1.373404 +v 6.772007 0.020326 1.406744 +v 7.003244 0.020326 1.530321 +v 8.433868 0.023645 3.017453 +v 8.571705 2.621381 2.937872 +v 8.618864 0.615620 2.910645 +v 7.803734 0.023645 2.196279 +v 7.954782 0.615620 2.045232 +v 7.902952 0.142910 2.097061 +v 7.413842 0.023645 1.854228 +v 7.499263 0.142910 1.742906 +v 7.461653 0.039097 1.791921 +v 7.202936 0.023645 1.703107 +v 7.246569 0.039097 1.637806 +v 7.225916 0.020326 1.668715 +v 7.439022 0.020326 1.821413 +v 7.859266 0.039097 2.140747 +v 7.614373 0.023645 2.018879 +v 7.666156 0.039097 1.959833 +v 7.641645 0.020326 1.987781 +v 7.832981 0.020326 2.167032 +v 8.555386 0.142910 2.947294 +v 8.145783 0.023645 2.586172 +v 8.257106 0.142910 2.500752 +v 8.208090 0.039097 2.538362 +v 7.981133 0.023645 2.385640 +v 8.040179 0.039097 2.333858 +v 8.012231 0.020326 2.358368 +v 8.178598 0.020326 2.560992 +v 8.501882 0.039097 2.978185 +v 8.296903 0.023645 2.797079 +v 8.362204 0.039097 2.753446 +v 8.331295 0.020326 2.774099 +v 8.469689 0.020326 2.996772 +v 9.178792 0.615620 5.000000 +v 8.830030 0.023645 3.973740 +v 9.036369 0.615620 3.918452 +v 8.965567 0.142910 3.937423 +v 8.663293 0.023645 3.482630 +v 8.792930 0.142910 3.428933 +v 8.735851 0.039097 3.452576 +v 8.556167 0.023645 3.246301 +v 8.626603 0.039097 3.211566 +v 8.593263 0.020326 3.228007 +v 8.701507 0.020326 3.466802 +v 8.905890 0.039097 3.953414 +v 8.754740 0.023645 3.725444 +v 8.829109 0.039097 3.700200 +v 8.793908 0.020326 3.712149 +v 8.869983 0.020326 3.963035 +v 9.105491 0.142910 5.000000 +v 8.931154 0.023645 4.482460 +v 9.070269 0.142910 4.464145 +v 9.009017 0.039097 4.472209 +v 8.888893 0.023645 4.226447 +v 8.965919 0.039097 4.211125 +v 8.929460 0.020326 4.218377 +v 8.972162 0.020326 4.477061 +v 9.043709 0.039097 5.000000 +v 8.956638 0.023645 4.740679 +v 9.035007 0.039097 4.735543 +v 8.997912 0.020326 4.737974 +v 9.006535 0.020326 5.000000 +v 6.791361 7.928881 1.897309 +v 6.941251 5.293516 1.637695 +v 5.000000 5.293516 1.117453 +v 5.000000 3.840676 0.974417 +v 7.012769 3.840676 1.513825 +v 5.000000 7.928881 1.417236 +v 5.000000 6.544681 1.254732 +v 6.872612 6.544681 1.756579 +v 8.882547 5.293516 5.000000 +v 8.362314 5.293516 3.058764 +v 8.486185 3.840676 2.987248 +v 9.025583 3.840676 5.000000 +v 8.102700 7.928881 3.208653 +v 8.243430 6.544681 3.127403 +v 8.745268 6.544681 5.000000 +v 3.739220 15.929955 2.816291 +v 1.753123 10.600694 5.000000 +v 3.376580 10.600694 2.188188 +v 2.188181 10.600694 3.376593 +v 1.575982 9.216277 5.000000 +v 2.034775 9.216277 3.288024 +v 3.288010 9.216277 2.034783 +v 2.109344 13.271226 5.000000 +v 3.554689 13.271226 2.496678 +v 2.496671 13.271226 3.554700 +v 1.924119 11.898438 5.000000 +v 2.336265 11.898438 3.462090 +v 3.462077 11.898438 2.336272 +v 2.816285 15.929955 3.739230 +v 2.288120 14.570229 5.000000 +v 2.651492 14.570229 3.644087 +v 3.644076 14.570229 2.651499 +v 8.246877 10.600694 5.000000 +v 6.623420 10.600694 2.188188 +v 5.000000 10.600694 1.753123 +v 5.000000 9.216277 1.575982 +v 6.711990 9.216277 2.034783 +v 7.811819 10.600694 3.376593 +v 7.965225 9.216277 3.288024 +v 8.424018 9.216277 5.000000 +v 6.260780 15.929955 2.816291 +v 6.445311 13.271226 2.496678 +v 5.000000 13.271226 2.109344 +v 5.000000 11.898438 1.924119 +v 6.537923 11.898438 2.336272 +v 5.000000 15.929955 2.478410 +v 5.000000 14.570229 2.288120 +v 6.355924 14.570229 2.651499 +v 7.890656 13.271226 5.000000 +v 7.503329 13.271226 3.554700 +v 7.663735 11.898438 3.462090 +v 8.075881 11.898438 5.000000 +v 7.183715 15.929955 3.739230 +v 7.348508 14.570229 3.644087 +v 7.711880 14.570229 5.000000 +v 6.982563 0.023645 8.433859 +v 6.791361 7.928881 8.102691 +v 7.062144 2.621381 8.571696 +v 8.433868 0.023645 6.982547 +v 8.571705 2.621381 7.062128 +v 8.618864 0.615620 7.089355 +v 8.830030 0.023645 6.026260 +v 9.036369 0.615620 6.081548 +v 8.965567 0.142910 6.062577 +v 8.931154 0.023645 5.517540 +v 9.070269 0.142910 5.535855 +v 9.009017 0.039097 5.527791 +v 8.956638 0.023645 5.259321 +v 9.035007 0.039097 5.264457 +v 8.997912 0.020326 5.262026 +v 8.972162 0.020326 5.522939 +v 8.905890 0.039097 6.046586 +v 8.888893 0.023645 5.773553 +v 8.965919 0.039097 5.788875 +v 8.929460 0.020326 5.781623 +v 8.869983 0.020326 6.036965 +v 8.555386 0.142910 7.052706 +v 8.663293 0.023645 6.517370 +v 8.792930 0.142910 6.571067 +v 8.735851 0.039097 6.547424 +v 8.754740 0.023645 6.274556 +v 8.829109 0.039097 6.299800 +v 8.793908 0.020326 6.287851 +v 8.701507 0.020326 6.533198 +v 8.501882 0.039097 7.021815 +v 8.556167 0.023645 6.753699 +v 8.626603 0.039097 6.788434 +v 8.593263 0.020326 6.771993 +v 8.469689 0.020326 7.003228 +v 7.089372 0.615620 8.618855 +v 7.803734 0.023645 7.803721 +v 7.954782 0.615620 7.954768 +v 7.902952 0.142910 7.902939 +v 8.145783 0.023645 7.413828 +v 8.257106 0.142910 7.499248 +v 8.208090 0.039097 7.461638 +v 8.296903 0.023645 7.202921 +v 8.362204 0.039097 7.246554 +v 8.331295 0.020326 7.225901 +v 8.178598 0.020326 7.439008 +v 7.859266 0.039097 7.859253 +v 7.981133 0.023645 7.614360 +v 8.040179 0.039097 7.666142 +v 8.012231 0.020326 7.641632 +v 7.832981 0.020326 7.832968 +v 7.052722 0.142910 8.555376 +v 7.413842 0.023645 8.145772 +v 7.499263 0.142910 8.257094 +v 7.461653 0.039097 8.208079 +v 7.614373 0.023645 7.981121 +v 7.666156 0.039097 8.040167 +v 7.641645 0.020326 8.012219 +v 7.439022 0.020326 8.178587 +v 7.021831 0.039097 8.501872 +v 7.202936 0.023645 8.296893 +v 7.246569 0.039097 8.362194 +v 7.225916 0.020326 8.331285 +v 7.003244 0.020326 8.469679 +v 6.941251 5.293516 8.362305 +v 8.362314 5.293516 6.941236 +v 8.486185 3.840676 7.012752 +v 7.012769 3.840676 8.486175 +v 8.102700 7.928881 6.791347 +v 8.243430 6.544681 6.872597 +v 6.872612 6.544681 8.243421 +v 3.017437 0.023645 8.433859 +v 2.937856 2.621381 8.571696 +v 5.000000 0.023645 8.965172 +v 5.000000 2.621381 9.124336 +v 5.000000 0.615620 9.178792 +v 6.026268 0.023645 8.830028 +v 6.081558 0.615620 9.036366 +v 6.062586 0.142910 8.965564 +v 6.517383 0.023645 8.663288 +v 6.571080 0.142910 8.792924 +v 6.547437 0.039097 8.735846 +v 6.753713 0.023645 8.556160 +v 6.788448 0.039097 8.626596 +v 6.772007 0.020326 8.593256 +v 6.533211 0.020326 8.701502 +v 6.046595 0.039097 8.905888 +v 6.274567 0.023645 8.754737 +v 6.299811 0.039097 8.829106 +v 6.287862 0.020326 8.793905 +v 6.036974 0.020326 8.869981 +v 5.000000 0.142910 9.105491 +v 5.517544 0.023645 8.931153 +v 5.535859 0.142910 9.070269 +v 5.527795 0.039097 9.009016 +v 5.773560 0.023645 8.888891 +v 5.788882 0.039097 8.965917 +v 5.781630 0.020326 8.929458 +v 5.522943 0.020326 8.972161 +v 5.000000 0.039097 9.043709 +v 5.259323 0.023645 8.956638 +v 5.264460 0.039097 9.035006 +v 5.262029 0.020326 8.997912 +v 5.000000 0.020326 9.006535 +v 2.910628 0.615620 8.618855 +v 3.973732 0.023645 8.830028 +v 3.918442 0.615620 9.036366 +v 3.937414 0.142910 8.965564 +v 4.482456 0.023645 8.931153 +v 4.464141 0.142910 9.070269 +v 4.472205 0.039097 9.009016 +v 4.740677 0.023645 8.956638 +v 4.735540 0.039097 9.035006 +v 4.737971 0.020326 8.997912 +v 4.477057 0.020326 8.972161 +v 3.953405 0.039097 8.905888 +v 4.226440 0.023645 8.888891 +v 4.211118 0.039097 8.965917 +v 4.218370 0.020326 8.929458 +v 3.963026 0.020326 8.869981 +v 2.947278 0.142910 8.555376 +v 3.482617 0.023645 8.663288 +v 3.428920 0.142910 8.792924 +v 3.452563 0.039097 8.735846 +v 3.725433 0.023645 8.754737 +v 3.700189 0.039097 8.829106 +v 3.712138 0.020326 8.793905 +v 3.466789 0.020326 8.701502 +v 2.978169 0.039097 8.501872 +v 3.246287 0.023645 8.556160 +v 3.211552 0.039097 8.626596 +v 3.227993 0.020326 8.593256 +v 2.996756 0.020326 8.469679 +v 1.566132 0.023645 6.982547 +v 1.428295 2.621381 7.062128 +v 1.381136 0.615620 7.089355 +v 2.196266 0.023645 7.803721 +v 2.045218 0.615620 7.954768 +v 2.097048 0.142910 7.902939 +v 2.586158 0.023645 8.145772 +v 2.500737 0.142910 8.257094 +v 2.538347 0.039097 8.208079 +v 2.797064 0.023645 8.296893 +v 2.753431 0.039097 8.362194 +v 2.774084 0.020326 8.331285 +v 2.560978 0.020326 8.178587 +v 2.140734 0.039097 7.859253 +v 2.385627 0.023645 7.981121 +v 2.333844 0.039097 8.040167 +v 2.358355 0.020326 8.012219 +v 2.167019 0.020326 7.832968 +v 1.444614 0.142910 7.052706 +v 1.854217 0.023645 7.413828 +v 1.742894 0.142910 7.499248 +v 1.791910 0.039097 7.461638 +v 2.018867 0.023645 7.614360 +v 1.959821 0.039097 7.666142 +v 1.987769 0.020326 7.641632 +v 1.821402 0.020326 7.439008 +v 1.498118 0.039097 7.021815 +v 1.703097 0.023645 7.202921 +v 1.637796 0.039097 7.246554 +v 1.668705 0.020326 7.225901 +v 1.530311 0.020326 7.003228 +v 1.169970 0.023645 6.026260 +v 0.963631 0.615620 6.081548 +v 1.034433 0.142910 6.062577 +v 1.336707 0.023645 6.517370 +v 1.207070 0.142910 6.571067 +v 1.264149 0.039097 6.547424 +v 1.443833 0.023645 6.753699 +v 1.373397 0.039097 6.788434 +v 1.406737 0.020326 6.771993 +v 1.298493 0.020326 6.533198 +v 1.094110 0.039097 6.046586 +v 1.245260 0.023645 6.274556 +v 1.170891 0.039097 6.299800 +v 1.206092 0.020326 6.287851 +v 1.130017 0.020326 6.036965 +v 3.208639 7.928881 8.102691 +v 3.058749 5.293516 8.362305 +v 5.000000 5.293516 8.882547 +v 5.000000 3.840676 9.025583 +v 2.987231 3.840676 8.486175 +v 5.000000 7.928881 8.582764 +v 5.000000 6.544681 8.745268 +v 3.127388 6.544681 8.243421 +v 1.637686 5.293516 6.941236 +v 1.513815 3.840676 7.012752 +v 1.897300 7.928881 6.791347 +v 1.756570 6.544681 6.872597 +v 6.260780 15.929955 7.183709 +v 6.623420 10.600694 7.811812 +v 7.811819 10.600694 6.623407 +v 7.965225 9.216277 6.711976 +v 6.711990 9.216277 7.965217 +v 6.445311 13.271226 7.503322 +v 7.503329 13.271226 6.445300 +v 7.663735 11.898438 6.537910 +v 6.537923 11.898438 7.663728 +v 7.183715 15.929955 6.260770 +v 7.348508 14.570229 6.355913 +v 6.355924 14.570229 7.348501 +v 3.376580 10.600694 7.811812 +v 5.000000 10.600694 8.246877 +v 5.000000 9.216277 8.424018 +v 3.288010 9.216277 7.965217 +v 2.188181 10.600694 6.623407 +v 2.034775 9.216277 6.711976 +v 3.739220 15.929955 7.183709 +v 3.554689 13.271226 7.503322 +v 5.000000 13.271226 7.890656 +v 5.000000 11.898438 8.075881 +v 3.462077 11.898438 7.663728 +v 5.000000 15.929955 7.521590 +v 5.000000 14.570229 7.711880 +v 3.644076 14.570229 7.348501 +v 2.496671 13.271226 6.445300 +v 2.336265 11.898438 6.537910 +v 2.816285 15.929955 6.260770 +v 2.651492 14.570229 6.355913 +vt 1.000000 0.916667 +vt 1.000000 1.000000 +vt 0.957053 0.916667 +vt 1.000000 0.416667 +vt 1.000000 0.500000 +vt 0.957053 0.416667 +vt 0.710046 0.416667 +vt 0.710046 0.500000 +vt 0.646478 0.416667 +vt 0.710046 0.083333 +vt 0.710046 0.166666 +vt 0.646478 0.083333 +vt 0.414458 0.083333 +vt 0.414458 0.166666 +vt 0.207229 0.166666 +vt 0.207229 0.000000 +vt 0.414458 0.000000 +vt 0.207229 0.083333 +vt 0.103615 0.083333 +vt 0.103615 0.062500 +vt 0.207229 0.041667 +vt 0.103615 0.041667 +vt 0.103615 0.020833 +vt 0.051807 0.041667 +vt 0.051807 0.031250 +vt 0.051807 0.020833 +vt 0.051807 0.010417 +vt 0.025904 0.010417 +vt 0.025904 0.000000 +vt 0.051807 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.010417 +vt 0.025904 0.020833 +vt 0.025904 0.031250 +vt 0.000000 0.020833 +vt 0.000000 0.031250 +vt 0.025904 0.041667 +vt 0.051807 0.083333 +vt 0.051807 0.072916 +vt 0.051807 0.062500 +vt 0.051807 0.052083 +vt 0.025904 0.052083 +vt 0.000000 0.041667 +vt 0.000000 0.052083 +vt 0.025904 0.062500 +vt 0.025904 0.072916 +vt 0.000000 0.062500 +vt 0.000000 0.072916 +vt 0.025904 0.083333 +vt 0.103615 0.145833 +vt 0.103615 0.125000 +vt 0.207229 0.125000 +vt 0.103615 0.104166 +vt 0.051807 0.125000 +vt 0.051807 0.114583 +vt 0.051807 0.104166 +vt 0.051807 0.093750 +vt 0.025904 0.093750 +vt 0.000000 0.083333 +vt 0.000000 0.093750 +vt 0.025904 0.104166 +vt 0.025904 0.114583 +vt 0.000000 0.104166 +vt 0.000000 0.114583 +vt 0.025904 0.125000 +vt 0.103615 0.166666 +vt 0.051807 0.166666 +vt 0.051807 0.156250 +vt 0.051807 0.145833 +vt 0.051807 0.135416 +vt 0.025904 0.135416 +vt 0.000000 0.125000 +vt 0.000000 0.135416 +vt 0.025904 0.145833 +vt 0.025904 0.156250 +vt 0.000000 0.145833 +vt 0.000000 0.156250 +vt 0.025904 0.166666 +vt 0.582909 0.083333 +vt 0.582909 0.166666 +vt 0.498684 0.083333 +vt 0.498684 0.000000 +vt 0.582909 0.000000 +vt 0.498684 0.166666 +vt 0.646478 0.000000 +vt 0.710046 0.000000 +vt 0.646478 0.166666 +vt 0.207229 0.458333 +vt 0.207229 0.416667 +vt 0.414458 0.416667 +vt 0.207229 0.250000 +vt 0.414458 0.250000 +vt 0.414458 0.333334 +vt 0.103615 0.250000 +vt 0.103615 0.229167 +vt 0.207229 0.208333 +vt 0.103615 0.208333 +vt 0.103615 0.187500 +vt 0.051807 0.208333 +vt 0.051807 0.197916 +vt 0.051807 0.187500 +vt 0.051807 0.177083 +vt 0.025904 0.177083 +vt 0.000000 0.166666 +vt 0.000000 0.177083 +vt 0.025904 0.187500 +vt 0.025904 0.197916 +vt 0.000000 0.187500 +vt 0.000000 0.197916 +vt 0.025904 0.208333 +vt 0.051807 0.250000 +vt 0.051807 0.239583 +vt 0.051807 0.229167 +vt 0.051807 0.218750 +vt 0.025904 0.218750 +vt 0.000000 0.208333 +vt 0.000000 0.218750 +vt 0.025904 0.229167 +vt 0.025904 0.239583 +vt 0.000000 0.229167 +vt 0.000000 0.239583 +vt 0.025904 0.250000 +vt 0.207229 0.333334 +vt 0.103615 0.333334 +vt 0.103615 0.312500 +vt 0.207229 0.291667 +vt 0.103615 0.291667 +vt 0.103615 0.270833 +vt 0.051807 0.291667 +vt 0.051807 0.281250 +vt 0.051807 0.270833 +vt 0.051807 0.260417 +vt 0.025904 0.260417 +vt 0.000000 0.250000 +vt 0.000000 0.260417 +vt 0.025904 0.270833 +vt 0.025904 0.281250 +vt 0.000000 0.270833 +vt 0.000000 0.281250 +vt 0.025904 0.291667 +vt 0.051807 0.333334 +vt 0.051807 0.322917 +vt 0.051807 0.312500 +vt 0.051807 0.302084 +vt 0.025904 0.302084 +vt 0.000000 0.291667 +vt 0.000000 0.302084 +vt 0.025904 0.312500 +vt 0.025904 0.322917 +vt 0.000000 0.312500 +vt 0.000000 0.322917 +vt 0.025904 0.333334 +vt 0.103615 0.416667 +vt 0.103615 0.395834 +vt 0.207229 0.375000 +vt 0.103615 0.375000 +vt 0.103615 0.354167 +vt 0.051807 0.375000 +vt 0.051807 0.364584 +vt 0.051807 0.354167 +vt 0.051807 0.343750 +vt 0.025904 0.343750 +vt 0.000000 0.333334 +vt 0.000000 0.343750 +vt 0.025904 0.354167 +vt 0.025904 0.364584 +vt 0.000000 0.354167 +vt 0.000000 0.364584 +vt 0.025904 0.375000 +vt 0.051807 0.416667 +vt 0.051807 0.406250 +vt 0.051807 0.395834 +vt 0.051807 0.385417 +vt 0.025904 0.385417 +vt 0.000000 0.375000 +vt 0.000000 0.385417 +vt 0.025904 0.395834 +vt 0.025904 0.406250 +vt 0.000000 0.395834 +vt 0.000000 0.406250 +vt 0.025904 0.416667 +vt 0.103615 0.479167 +vt 0.103615 0.458333 +vt 0.103615 0.437500 +vt 0.051807 0.458333 +vt 0.051807 0.447917 +vt 0.051807 0.437500 +vt 0.051807 0.427084 +vt 0.025904 0.427084 +vt 0.000000 0.416667 +vt 0.000000 0.427084 +vt 0.025904 0.437500 +vt 0.025904 0.447917 +vt 0.000000 0.437500 +vt 0.000000 0.447917 +vt 0.025904 0.458333 +vt 0.051807 0.489583 +vt 0.051807 0.479167 +vt 0.051807 0.468750 +vt 0.025904 0.468750 +vt 0.000000 0.458333 +vt 0.000000 0.468750 +vt 0.025904 0.479167 +vt 0.025904 0.489583 +vt 0.051807 0.500000 +vt 0.000000 0.479167 +vt 0.000000 0.489583 +vt 0.025904 0.500000 +vt 0.710046 0.250000 +vt 0.710046 0.333334 +vt 0.646478 0.250000 +vt 0.498684 0.250000 +vt 0.582909 0.250000 +vt 0.582909 0.333334 +vt 0.498684 0.333334 +vt 0.646478 0.333334 +vt 0.498684 0.416667 +vt 0.582909 0.416667 +vt 0.582909 0.500000 +vt 0.498684 0.500000 +vt 0.646478 0.500000 +vt 1.000000 0.083333 +vt 1.000000 0.166666 +vt 0.957053 0.083333 +vt 0.818618 0.083333 +vt 0.818618 0.166666 +vt 0.764332 0.083333 +vt 0.764332 0.000000 +vt 0.818618 0.000000 +vt 0.764332 0.166666 +vt 0.914105 0.083333 +vt 0.914105 0.166666 +vt 0.866362 0.083333 +vt 0.866362 0.000000 +vt 0.914105 0.000000 +vt 0.866362 0.166666 +vt 0.957053 0.000000 +vt 1.000000 0.000000 +vt 0.957053 0.166666 +vt 0.764332 0.416667 +vt 0.818618 0.416667 +vt 0.818618 0.500000 +vt 0.764332 0.250000 +vt 0.818618 0.250000 +vt 0.818618 0.333334 +vt 0.764332 0.333334 +vt 0.764332 0.500000 +vt 1.000000 0.250000 +vt 1.000000 0.333334 +vt 0.957053 0.250000 +vt 0.866362 0.250000 +vt 0.914105 0.250000 +vt 0.914105 0.333334 +vt 0.866362 0.333334 +vt 0.957053 0.333334 +vt 0.866362 0.416667 +vt 0.914105 0.416667 +vt 0.914105 0.500000 +vt 0.866362 0.500000 +vt 0.957053 0.500000 +vt 0.646478 0.916667 +vt 0.710046 0.916667 +vt 0.710046 1.000000 +vt 0.710046 0.583333 +vt 0.710046 0.666666 +vt 0.646478 0.583333 +vt 0.414458 0.583333 +vt 0.414458 0.666666 +vt 0.207229 0.666666 +vt 0.207229 0.500000 +vt 0.414458 0.500000 +vt 0.207229 0.583333 +vt 0.103615 0.583333 +vt 0.103615 0.562500 +vt 0.207229 0.541667 +vt 0.103615 0.541667 +vt 0.103615 0.520833 +vt 0.051807 0.541667 +vt 0.051807 0.531250 +vt 0.051807 0.520833 +vt 0.051807 0.510417 +vt 0.025904 0.510417 +vt 0.000000 0.500000 +vt 0.000000 0.510417 +vt 0.025904 0.520833 +vt 0.025904 0.531250 +vt 0.000000 0.520833 +vt 0.000000 0.531250 +vt 0.025904 0.541667 +vt 0.051807 0.583333 +vt 0.051807 0.572916 +vt 0.051807 0.562500 +vt 0.051807 0.552083 +vt 0.025904 0.552083 +vt 0.000000 0.541667 +vt 0.000000 0.552083 +vt 0.025904 0.562500 +vt 0.025904 0.572916 +vt 0.000000 0.562500 +vt 0.000000 0.572916 +vt 0.025904 0.583333 +vt 0.103615 0.666666 +vt 0.103615 0.645833 +vt 0.207229 0.625000 +vt 0.103615 0.625000 +vt 0.103615 0.604166 +vt 0.051807 0.625000 +vt 0.051807 0.614583 +vt 0.051807 0.604166 +vt 0.051807 0.593750 +vt 0.025904 0.593750 +vt 0.000000 0.583333 +vt 0.000000 0.593750 +vt 0.025904 0.604166 +vt 0.025904 0.614583 +vt 0.000000 0.604166 +vt 0.000000 0.614583 +vt 0.025904 0.625000 +vt 0.051807 0.666666 +vt 0.051807 0.656250 +vt 0.051807 0.645833 +vt 0.051807 0.635416 +vt 0.025904 0.635416 +vt 0.000000 0.625000 +vt 0.000000 0.635416 +vt 0.025904 0.645833 +vt 0.025904 0.656250 +vt 0.000000 0.645833 +vt 0.000000 0.656250 +vt 0.025904 0.666666 +vt 0.582909 0.583333 +vt 0.582909 0.666666 +vt 0.498684 0.583333 +vt 0.498684 0.666666 +vt 0.646478 0.666666 +vt 0.207229 0.958333 +vt 0.207229 0.916667 +vt 0.414458 0.916667 +vt 0.207229 0.750000 +vt 0.414458 0.750000 +vt 0.414458 0.833334 +vt 0.103615 0.750000 +vt 0.103615 0.729167 +vt 0.207229 0.708333 +vt 0.103615 0.708333 +vt 0.103615 0.687500 +vt 0.051807 0.708333 +vt 0.051807 0.697916 +vt 0.051807 0.687500 +vt 0.051807 0.677083 +vt 0.025904 0.677083 +vt 0.000000 0.666666 +vt 0.000000 0.677083 +vt 0.025904 0.687500 +vt 0.025904 0.697916 +vt 0.000000 0.687500 +vt 0.000000 0.697916 +vt 0.025904 0.708333 +vt 0.051807 0.750000 +vt 0.051807 0.739583 +vt 0.051807 0.729167 +vt 0.051807 0.718750 +vt 0.025904 0.718750 +vt 0.000000 0.708333 +vt 0.000000 0.718750 +vt 0.025904 0.729167 +vt 0.025904 0.739583 +vt 0.000000 0.729167 +vt 0.000000 0.739583 +vt 0.025904 0.750000 +vt 0.207229 0.833334 +vt 0.103615 0.833334 +vt 0.103615 0.812500 +vt 0.207229 0.791667 +vt 0.103615 0.791667 +vt 0.103615 0.770833 +vt 0.051807 0.791667 +vt 0.051807 0.781250 +vt 0.051807 0.770833 +vt 0.051807 0.760417 +vt 0.025904 0.760417 +vt 0.000000 0.750000 +vt 0.000000 0.760417 +vt 0.025904 0.770833 +vt 0.025904 0.781250 +vt 0.000000 0.770833 +vt 0.000000 0.781250 +vt 0.025904 0.791667 +vt 0.051807 0.833334 +vt 0.051807 0.822917 +vt 0.051807 0.812500 +vt 0.051807 0.802084 +vt 0.025904 0.802084 +vt 0.000000 0.791667 +vt 0.000000 0.802084 +vt 0.025904 0.812500 +vt 0.025904 0.822917 +vt 0.000000 0.812500 +vt 0.000000 0.822917 +vt 0.025904 0.833334 +vt 0.103615 0.916667 +vt 0.103615 0.895834 +vt 0.207229 0.875000 +vt 0.103615 0.875000 +vt 0.103615 0.854167 +vt 0.051807 0.875000 +vt 0.051807 0.864584 +vt 0.051807 0.854167 +vt 0.051807 0.843750 +vt 0.025904 0.843750 +vt 0.000000 0.833334 +vt 0.000000 0.843750 +vt 0.025904 0.854167 +vt 0.025904 0.864584 +vt 0.000000 0.854167 +vt 0.000000 0.864584 +vt 0.025904 0.875000 +vt 0.051807 0.916667 +vt 0.051807 0.906250 +vt 0.051807 0.895834 +vt 0.051807 0.885417 +vt 0.025904 0.885417 +vt 0.000000 0.875000 +vt 0.000000 0.885417 +vt 0.025904 0.895834 +vt 0.025904 0.906250 +vt 0.000000 0.895834 +vt 0.000000 0.906250 +vt 0.025904 0.916667 +vt 0.103615 0.958333 +vt 0.207229 1.000000 +vt 0.103615 0.937500 +vt 0.051807 0.958333 +vt 0.051807 0.947917 +vt 0.051807 0.937500 +vt 0.051807 0.927084 +vt 0.025904 0.927084 +vt 0.000000 0.916667 +vt 0.000000 0.927084 +vt 0.025904 0.937500 +vt 0.025904 0.947917 +vt 0.000000 0.937500 +vt 0.000000 0.947917 +vt 0.025904 0.958333 +vt 0.000000 1.000000 +vt 0.000000 0.958333 +vt 0.710046 0.750000 +vt 0.710046 0.833334 +vt 0.646478 0.750000 +vt 0.498684 0.750000 +vt 0.582909 0.750000 +vt 0.582909 0.833334 +vt 0.498684 0.833334 +vt 0.646478 0.833334 +vt 0.498684 0.916667 +vt 0.582909 0.916667 +vt 0.582909 1.000000 +vt 0.498684 1.000000 +vt 0.646478 1.000000 +vt 1.000000 0.583333 +vt 1.000000 0.666666 +vt 0.957053 0.583333 +vt 0.764332 0.583333 +vt 0.818618 0.583333 +vt 0.818618 0.666666 +vt 0.764332 0.666666 +vt 0.866362 0.583333 +vt 0.914105 0.583333 +vt 0.914105 0.666666 +vt 0.866362 0.666666 +vt 0.957053 0.666666 +vt 0.764332 0.916667 +vt 0.818618 0.916667 +vt 0.818618 1.000000 +vt 0.764332 0.750000 +vt 0.818618 0.750000 +vt 0.818618 0.833334 +vt 0.764332 0.833334 +vt 0.764332 1.000000 +vt 1.000000 0.750000 +vt 1.000000 0.833334 +vt 0.957053 0.750000 +vt 0.866362 0.750000 +vt 0.914105 0.750000 +vt 0.914105 0.833334 +vt 0.866362 0.833334 +vt 0.957053 0.833334 +vt 0.866362 0.916667 +vt 0.914105 0.916667 +vt 0.914105 1.000000 +vt 0.866362 1.000000 +vt 0.957053 1.000000 +vt 0.103615 0.000000 +vt 0.103615 0.500000 +vt 0.414458 1.000000 +vt 0.103615 1.000000 +vt 0.051807 1.000000 +vt 0.025904 1.000000 +vn -0.855158 0.138592 0.499497 +vn -0.990337 0.138595 0.004983 +vn -0.855477 0.137445 0.499267 +vn 0.855158 0.138592 -0.499497 +vn 0.990337 0.138595 -0.004983 +vn 0.855477 0.137445 -0.499267 +vn 0.858038 0.119287 -0.499541 +vn 0.992853 0.119290 -0.003582 +vn 0.858835 0.112906 -0.499655 +vn -0.861619 0.119288 -0.493338 +vn -0.499543 0.119288 -0.858037 +vn -0.862116 0.112906 -0.493972 +vn -0.864783 0.062737 -0.498211 +vn -0.522059 0.054243 -0.851183 +vn -0.559013 0.035015 -0.828420 +vn -0.998818 0.048476 0.003588 +vn -0.998889 0.047128 0.000794 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.848748 -0.198912 -0.489960 +vn -0.915190 -0.136671 -0.379143 +vn -0.970776 0.085464 -0.224254 +vn -0.946638 -0.198907 -0.253600 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.753817 -0.625309 -0.201863 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.773684 -0.625316 -0.101943 +vn -0.834536 -0.548214 -0.054865 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.774567 -0.626221 0.088845 +vn -0.834536 -0.548214 -0.054865 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.199250 -0.979861 -0.013125 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.753817 -0.625309 -0.201863 +vn -0.197953 -0.979864 -0.026106 +vn -0.773684 -0.625316 -0.101943 +vn -0.820199 -0.548350 -0.163050 +vn 0.079314 -0.996795 0.010461 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn -0.195829 -0.979864 -0.038953 +vn -0.192889 -0.979859 -0.051676 +vn -0.848748 -0.198912 -0.489960 +vn -0.675878 -0.625313 -0.390093 +vn -0.749973 -0.548375 -0.369898 +vn -0.915190 -0.136671 -0.379143 +vn -0.720908 -0.625314 -0.298787 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.192889 -0.979859 -0.051676 +vn -0.753817 -0.625309 -0.201863 +vn -0.792045 -0.548040 -0.268918 +vn 0.077272 -0.996795 0.020703 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn -0.189096 -0.979856 -0.064228 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.675878 -0.625313 -0.390093 +vn -0.184454 -0.979861 -0.076474 +vn -0.720908 -0.625314 -0.298787 +vn -0.749973 -0.548375 -0.369898 +vn 0.073898 -0.996795 0.030640 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn -0.179057 -0.979865 -0.088341 +vn -0.172924 -0.979863 -0.099831 +vn -0.603081 -0.136554 -0.785905 +vn -0.692977 -0.198918 -0.692975 +vn -0.679581 0.085468 -0.728605 +vn -0.679581 0.085468 -0.728605 +vn -0.692977 -0.198918 -0.692975 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.551796 -0.625317 -0.551816 +vn -0.628648 -0.548296 -0.551520 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.619062 -0.625306 -0.475137 +vn -0.172924 -0.979863 -0.099831 +vn -0.675878 -0.625313 -0.390093 +vn -0.695502 -0.548117 -0.464591 +vn 0.069281 -0.996795 0.039999 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn -0.166042 -0.979858 -0.110944 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.551796 -0.625317 -0.551816 +vn -0.158405 -0.979857 -0.121607 +vn -0.619062 -0.625306 -0.475137 +vn -0.628648 -0.548296 -0.551520 +vn 0.063454 -0.996795 0.048715 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn -0.150082 -0.979862 -0.131702 +vn -0.141165 -0.979865 -0.141202 +vn -0.489963 -0.198913 -0.848746 +vn -0.390067 -0.625315 -0.675892 +vn -0.464580 -0.548113 -0.695513 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.475115 -0.625305 -0.619080 +vn -0.141165 -0.979865 -0.141202 +vn -0.551796 -0.625317 -0.551816 +vn -0.551508 -0.548294 -0.628659 +vn 0.056560 -0.996795 0.056577 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn -0.131662 -0.979863 -0.150115 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.390067 -0.625315 -0.675892 +vn -0.121566 -0.979857 -0.158438 +vn -0.475115 -0.625305 -0.619080 +vn -0.464580 -0.548113 -0.695513 +vn 0.048696 -0.996795 0.063468 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn -0.110900 -0.979858 -0.166071 +vn -0.099785 -0.979863 -0.172949 +vn -0.862907 0.102956 -0.494765 +vn -0.499945 0.102956 -0.859916 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.994681 0.102958 0.002990 +vn -0.862907 0.102956 -0.494765 +vn -0.998889 0.047128 0.000794 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.863780 0.089908 -0.495782 +vn -0.500192 0.089907 -0.861234 +vn -0.993600 0.112908 0.003282 +vn -0.992853 0.119290 0.003582 +vn -0.861619 0.119288 -0.493338 +vn -0.994681 0.102958 0.002990 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.862116 0.112906 -0.493972 +vn -0.499657 0.112906 -0.858834 +vn 0.970776 0.085464 -0.224254 +vn 0.865986 0.007573 -0.500011 +vn 0.863839 0.062737 -0.499846 +vn -0.000000 0.054620 -0.998507 +vn -0.000794 0.047128 -0.998889 +vn 0.520588 0.054246 -0.852083 +vn -0.522059 0.054243 -0.851183 +vn -0.000794 0.047128 -0.998889 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.000000 -0.198908 -0.980018 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.253603 -0.198906 -0.946637 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.201834 -0.625309 -0.753825 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.298761 -0.625313 -0.720920 +vn -0.099785 -0.979863 -0.172949 +vn -0.390067 -0.625315 -0.675892 +vn -0.369884 -0.548374 -0.749982 +vn 0.039978 -0.996795 0.069293 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn -0.088294 -0.979865 -0.179080 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.201834 -0.625309 -0.753825 +vn -0.076426 -0.979861 -0.184474 +vn -0.298761 -0.625313 -0.720920 +vn -0.268901 -0.548039 -0.792052 +vn 0.030617 -0.996795 0.073907 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn -0.064178 -0.979856 -0.189113 +vn -0.051625 -0.979859 -0.192902 +vn 0.000000 -0.198908 -0.980018 +vn 0.000016 -0.625302 -0.780383 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn -0.101911 -0.625316 -0.773688 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.051625 -0.979859 -0.192902 +vn -0.201834 -0.625309 -0.753825 +vn -0.163032 -0.548348 -0.820204 +vn 0.020680 -0.996795 0.077279 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn -0.038902 -0.979864 -0.195841 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn 0.000016 -0.625302 -0.780383 +vn -0.026053 -0.979864 -0.197959 +vn -0.101911 -0.625316 -0.773688 +vn -0.054845 -0.548214 -0.834538 +vn 0.010437 -0.996795 0.079315 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn -0.013072 -0.979860 -0.199255 +vn 0.000027 -0.979855 -0.199708 +vn 0.559013 0.035015 -0.828420 +vn 0.489963 -0.198913 -0.848746 +vn 0.379146 -0.136670 -0.915188 +vn 0.224256 0.085466 -0.970775 +vn 0.253603 -0.198906 -0.946637 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.201864 -0.625309 -0.753817 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.101942 -0.625316 -0.773684 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.000027 -0.979855 -0.199708 +vn 0.000016 -0.625302 -0.780383 +vn 0.054866 -0.548214 -0.834537 +vn -0.000012 -0.996795 0.079997 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn 0.013125 -0.979860 -0.199252 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.201864 -0.625309 -0.753817 +vn 0.026105 -0.979864 -0.197952 +vn 0.101942 -0.625316 -0.773684 +vn 0.163052 -0.548348 -0.820200 +vn -0.010461 -0.996795 0.079312 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn 0.038954 -0.979864 -0.195830 +vn 0.051676 -0.979859 -0.192887 +vn 0.489963 -0.198913 -0.848746 +vn 0.390094 -0.625314 -0.675876 +vn 0.369902 -0.548374 -0.749972 +vn 0.379146 -0.136670 -0.915188 +vn 0.298790 -0.625312 -0.720908 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.051676 -0.979859 -0.192887 +vn 0.201864 -0.625309 -0.753817 +vn 0.268920 -0.548039 -0.792045 +vn -0.020704 -0.996795 0.077272 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn 0.064229 -0.979856 -0.189096 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.390094 -0.625314 -0.675876 +vn 0.076475 -0.979861 -0.184454 +vn 0.298790 -0.625312 -0.720908 +vn 0.369902 -0.548374 -0.749972 +vn -0.030640 -0.996795 0.073898 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn 0.088341 -0.979865 -0.179057 +vn 0.099830 -0.979863 -0.172922 +vn 0.559013 0.035015 -0.828420 +vn 0.520588 0.054246 -0.852083 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.848748 -0.198912 -0.489960 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.692977 -0.198918 -0.692975 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551819 -0.625315 -0.551794 +vn 0.551523 -0.548295 -0.628645 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.475140 -0.625305 -0.619061 +vn 0.099830 -0.979863 -0.172922 +vn 0.390094 -0.625314 -0.675876 +vn 0.464597 -0.548113 -0.695501 +vn -0.039999 -0.996795 0.069281 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn 0.110944 -0.979858 -0.166042 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.551819 -0.625315 -0.551794 +vn 0.121608 -0.979857 -0.158406 +vn 0.475140 -0.625305 -0.619061 +vn 0.551523 -0.548295 -0.628645 +vn -0.048715 -0.996795 0.063453 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn 0.131702 -0.979863 -0.150080 +vn 0.141203 -0.979865 -0.141164 +vn 0.848748 -0.198912 -0.489960 +vn 0.675893 -0.625315 -0.390065 +vn 0.695513 -0.548117 -0.464574 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.619082 -0.625304 -0.475112 +vn 0.141203 -0.979865 -0.141164 +vn 0.551819 -0.625315 -0.551794 +vn 0.628661 -0.548296 -0.551504 +vn -0.056577 -0.996795 0.056559 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn 0.150116 -0.979863 -0.131661 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.675893 -0.625315 -0.390065 +vn 0.158439 -0.979857 -0.121565 +vn 0.619082 -0.625304 -0.475112 +vn 0.695513 -0.548117 -0.464574 +vn -0.063469 -0.996795 0.048696 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn 0.166073 -0.979858 -0.110900 +vn 0.172949 -0.979863 -0.099784 +vn 0.982121 -0.136787 -0.129332 +vn 0.946638 -0.198907 -0.253600 +vn 0.970776 0.085464 -0.224254 +vn 0.970776 0.085464 -0.224254 +vn 0.946638 -0.198907 -0.253600 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.753824 -0.625311 -0.201832 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.720921 -0.625312 -0.298759 +vn 0.172949 -0.979863 -0.099784 +vn 0.675893 -0.625315 -0.390065 +vn 0.749983 -0.548375 -0.369880 +vn -0.069293 -0.996795 0.039977 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn 0.179081 -0.979865 -0.088293 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.753824 -0.625311 -0.201832 +vn 0.184475 -0.979861 -0.076425 +vn 0.720921 -0.625312 -0.298759 +vn 0.792052 -0.548040 -0.268898 +vn -0.073908 -0.996795 0.030617 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn 0.189113 -0.979856 -0.064178 +vn 0.192902 -0.979859 -0.051624 +vn 0.834538 -0.548214 -0.054844 +vn 0.773688 -0.625316 -0.101912 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.773688 -0.625316 -0.101912 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.192902 -0.979859 -0.051624 +vn 0.753824 -0.625311 -0.201832 +vn 0.820204 -0.548349 -0.163030 +vn -0.077279 -0.996795 0.020680 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn 0.195842 -0.979864 -0.038902 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.780383 -0.625302 0.000016 +vn 0.197959 -0.979864 -0.026053 +vn 0.773688 -0.625316 -0.101912 +vn 0.834538 -0.548214 -0.054844 +vn -0.079316 -0.996795 0.010437 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn 0.199256 -0.979860 -0.013072 +vn 0.199709 -0.979855 0.000026 +vn -0.003582 0.119290 -0.992853 +vn 0.493340 0.119288 -0.861618 +vn -0.003282 0.112908 -0.993600 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn 0.494767 0.102956 -0.862905 +vn -0.500192 0.089907 -0.861234 +vn -0.499945 0.102956 -0.859916 +vn -0.002990 0.102958 -0.994681 +vn -0.522059 0.054243 -0.851183 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.002546 0.089909 -0.995947 +vn 0.495785 0.089908 -0.863779 +vn -0.499543 0.119288 -0.858037 +vn -0.003582 0.119290 -0.992853 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.003282 0.112908 -0.993600 +vn 0.493974 0.112906 -0.862115 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.994681 0.102958 -0.002990 +vn 0.495785 0.089908 -0.863779 +vn 0.494767 0.102956 -0.862905 +vn 0.859917 0.102956 -0.499943 +vn 0.520588 0.054246 -0.852083 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.861235 0.089907 -0.500190 +vn 0.995947 0.089909 -0.002546 +vn 0.493340 0.119288 -0.861618 +vn 0.858038 0.119287 -0.499541 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.858835 0.112906 -0.499655 +vn 0.993600 0.112908 -0.003282 +vn -0.860140 0.138592 -0.490867 +vn -0.499499 0.138592 -0.855157 +vn -0.860102 0.137445 -0.491258 +vn -0.860841 0.128646 -0.492344 +vn -0.499366 0.128646 -0.856787 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.991682 0.128649 0.004054 +vn -0.860841 0.128646 -0.492344 +vn -0.992853 0.119290 0.003582 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.861162 0.124651 -0.492811 +vn -0.499410 0.124651 -0.857352 +vn -0.860318 0.134936 -0.491574 +vn -0.499299 0.134937 -0.855858 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.990844 0.134939 0.004460 +vn -0.860318 0.134936 -0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.860532 0.132157 -0.491955 +vn -0.499292 0.132157 -0.856295 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.860140 0.138592 -0.490867 +vn -0.990844 0.134939 0.004460 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.860102 0.137445 -0.491258 +vn -0.499269 0.137445 -0.855476 +vn 0.857353 0.124650 -0.499408 +vn 0.856788 0.128646 -0.499364 +vn 0.991682 0.128649 -0.004054 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn 0.492346 0.128646 -0.860840 +vn -0.499410 0.124651 -0.857352 +vn -0.499366 0.128646 -0.856787 +vn -0.004054 0.128649 -0.991682 +vn -0.499543 0.119288 -0.858037 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.003810 0.124653 -0.992193 +vn 0.492814 0.124651 -0.861160 +vn 0.492814 0.124651 -0.861160 +vn 0.492346 0.128646 -0.860840 +vn 0.856788 0.128646 -0.499364 +vn 0.493340 0.119288 -0.861618 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.857353 0.124650 -0.499408 +vn 0.992193 0.124653 -0.003810 +vn -0.004983 0.138595 -0.990337 +vn 0.490869 0.138592 -0.860139 +vn -0.004625 0.137448 -0.990498 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn 0.491576 0.134936 -0.860317 +vn -0.499292 0.132157 -0.856295 +vn -0.499299 0.134937 -0.855858 +vn -0.004460 0.134939 -0.990844 +vn -0.499366 0.128646 -0.856787 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.004236 0.132159 -0.991220 +vn 0.491957 0.132157 -0.860530 +vn -0.499499 0.138592 -0.855157 +vn -0.004983 0.138595 -0.990337 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.004625 0.137448 -0.990498 +vn 0.491260 0.137445 -0.860100 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.990844 0.134939 -0.004460 +vn 0.491957 0.132157 -0.860530 +vn 0.491576 0.134936 -0.860317 +vn 0.855859 0.134936 -0.499297 +vn 0.492346 0.128646 -0.860840 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.856296 0.132157 -0.499291 +vn 0.991220 0.132159 -0.004236 +vn 0.490869 0.138592 -0.860139 +vn 0.855158 0.138592 -0.499497 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.855477 0.137445 -0.499267 +vn 0.990498 0.137448 -0.004625 +vn -0.858835 0.112906 0.499655 +vn -0.858038 0.119288 0.499541 +vn -0.992853 0.119290 0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.499543 0.119288 0.858037 +vn 0.862116 0.112906 0.493972 +vn 0.864783 0.062737 0.498211 +vn 0.522059 0.054243 0.851183 +vn 0.559013 0.035015 0.828420 +vn 0.998507 0.054619 0.000000 +vn 0.998889 0.047128 -0.000794 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.848748 -0.198912 0.489960 +vn 0.915190 -0.136671 0.379143 +vn 0.970776 0.085464 0.224254 +vn 0.946638 -0.198907 0.253600 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.753817 -0.625309 0.201863 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.773684 -0.625316 0.101943 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.199709 -0.979855 0.000026 +vn 0.780383 -0.625302 0.000016 +vn 0.834536 -0.548215 0.054865 +vn -0.079997 -0.996795 -0.000012 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn 0.199250 -0.979861 0.013125 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.753817 -0.625309 0.201863 +vn 0.197953 -0.979864 0.026106 +vn 0.773684 -0.625316 0.101943 +vn 0.820199 -0.548350 0.163050 +vn -0.079314 -0.996795 -0.010461 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn 0.195829 -0.979864 0.038953 +vn 0.192889 -0.979859 0.051676 +vn 0.848748 -0.198912 0.489960 +vn 0.675878 -0.625313 0.390093 +vn 0.749973 -0.548375 0.369898 +vn 0.915190 -0.136671 0.379143 +vn 0.720908 -0.625314 0.298787 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.192889 -0.979859 0.051676 +vn 0.753817 -0.625309 0.201863 +vn 0.792045 -0.548040 0.268918 +vn -0.077272 -0.996795 -0.020703 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn 0.189096 -0.979856 0.064228 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.675878 -0.625313 0.390093 +vn 0.184454 -0.979861 0.076474 +vn 0.720908 -0.625314 0.298787 +vn 0.749973 -0.548375 0.369898 +vn -0.073898 -0.996795 -0.030640 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn 0.179057 -0.979865 0.088341 +vn 0.172924 -0.979863 0.099831 +vn 0.559013 0.035015 0.828420 +vn 0.489963 -0.198913 0.848746 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.692977 -0.198918 0.692975 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.551796 -0.625317 0.551816 +vn 0.628648 -0.548296 0.551520 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.619062 -0.625306 0.475137 +vn 0.172924 -0.979863 0.099831 +vn 0.675878 -0.625313 0.390093 +vn 0.695502 -0.548117 0.464591 +vn -0.069281 -0.996795 -0.039999 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn 0.166042 -0.979858 0.110944 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.551796 -0.625317 0.551816 +vn 0.158405 -0.979857 0.121607 +vn 0.619062 -0.625306 0.475137 +vn 0.628648 -0.548296 0.551520 +vn -0.063454 -0.996795 -0.048715 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn 0.150082 -0.979862 0.131702 +vn 0.141165 -0.979865 0.141202 +vn 0.489963 -0.198913 0.848746 +vn 0.390067 -0.625315 0.675892 +vn 0.464580 -0.548113 0.695513 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.475115 -0.625305 0.619080 +vn 0.141165 -0.979865 0.141202 +vn 0.551796 -0.625317 0.551816 +vn 0.551508 -0.548294 0.628659 +vn -0.056560 -0.996795 -0.056577 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn 0.131662 -0.979863 0.150115 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.390067 -0.625315 0.675892 +vn 0.121566 -0.979857 0.158438 +vn 0.475115 -0.625305 0.619080 +vn 0.464580 -0.548113 0.695513 +vn -0.048696 -0.996795 -0.063468 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn 0.110900 -0.979858 0.166071 +vn 0.099785 -0.979863 0.172949 +vn 0.862907 0.102956 0.494765 +vn 0.499945 0.102956 0.859916 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.994681 0.102958 -0.002990 +vn 0.862907 0.102956 0.494765 +vn 0.998889 0.047128 -0.000794 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.863780 0.089908 0.495782 +vn 0.500192 0.089907 0.861234 +vn 0.993600 0.112908 -0.003282 +vn 0.992853 0.119290 -0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.994681 0.102958 -0.002990 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.862116 0.112906 0.493972 +vn 0.499657 0.112906 0.858834 +vn -0.972486 0.075824 0.220276 +vn -0.865986 0.007573 0.500011 +vn -0.863839 0.062737 0.499846 +vn 0.000000 0.054620 0.998507 +vn 0.000794 0.047128 0.998889 +vn -0.520588 0.054246 0.852083 +vn 0.522059 0.054243 0.851183 +vn 0.000794 0.047128 0.998889 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn 0.000000 -0.198908 0.980018 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.253603 -0.198906 0.946637 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.201834 -0.625309 0.753825 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.298761 -0.625313 0.720920 +vn 0.099785 -0.979863 0.172949 +vn 0.390067 -0.625315 0.675892 +vn 0.369884 -0.548374 0.749982 +vn -0.039978 -0.996795 -0.069293 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn 0.088294 -0.979865 0.179080 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.201834 -0.625309 0.753825 +vn 0.076426 -0.979861 0.184474 +vn 0.298761 -0.625313 0.720920 +vn 0.268901 -0.548039 0.792052 +vn -0.030617 -0.996795 -0.073907 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn 0.064178 -0.979856 0.189113 +vn 0.051625 -0.979859 0.192902 +vn 0.000000 -0.198908 0.980018 +vn -0.000016 -0.625302 0.780383 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.101911 -0.625316 0.773688 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.051625 -0.979859 0.192902 +vn 0.201834 -0.625309 0.753825 +vn 0.163032 -0.548348 0.820204 +vn -0.020680 -0.996795 -0.077279 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn 0.038902 -0.979864 0.195841 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn -0.000016 -0.625302 0.780383 +vn 0.026053 -0.979864 0.197959 +vn 0.101911 -0.625316 0.773688 +vn 0.054845 -0.548214 0.834538 +vn -0.010437 -0.996795 -0.079315 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn 0.013072 -0.979860 0.199255 +vn -0.000027 -0.979855 0.199708 +vn -0.559013 0.035015 0.828420 +vn -0.489963 -0.198913 0.848746 +vn -0.379146 -0.136670 0.915188 +vn -0.224256 0.085466 0.970775 +vn -0.253603 -0.198906 0.946637 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.201864 -0.625309 0.753817 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.101942 -0.625316 0.773684 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.000027 -0.979855 0.199708 +vn -0.000016 -0.625302 0.780383 +vn -0.054866 -0.548214 0.834537 +vn 0.000012 -0.996795 -0.079997 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn -0.013125 -0.979860 0.199252 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.201864 -0.625309 0.753817 +vn -0.026105 -0.979864 0.197952 +vn -0.101942 -0.625316 0.773684 +vn -0.163052 -0.548348 0.820200 +vn 0.010461 -0.996795 -0.079312 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn -0.038954 -0.979864 0.195830 +vn -0.051676 -0.979859 0.192887 +vn -0.489963 -0.198913 0.848746 +vn -0.390094 -0.625314 0.675876 +vn -0.369902 -0.548374 0.749972 +vn -0.379146 -0.136670 0.915188 +vn -0.298790 -0.625312 0.720908 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.051676 -0.979859 0.192887 +vn -0.201864 -0.625309 0.753817 +vn -0.268920 -0.548039 0.792045 +vn 0.020704 -0.996795 -0.077272 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn -0.064229 -0.979856 0.189096 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.390094 -0.625314 0.675876 +vn -0.076475 -0.979861 0.184454 +vn -0.298790 -0.625312 0.720908 +vn -0.369902 -0.548374 0.749972 +vn 0.030640 -0.996795 -0.073898 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn -0.088341 -0.979865 0.179057 +vn -0.099830 -0.979863 0.172922 +vn -0.559013 0.035015 0.828420 +vn -0.520588 0.054246 0.852083 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.848748 -0.198912 0.489960 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.692977 -0.198918 0.692975 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551819 -0.625315 0.551794 +vn -0.551523 -0.548295 0.628645 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.475140 -0.625305 0.619061 +vn -0.099830 -0.979863 0.172922 +vn -0.390094 -0.625314 0.675876 +vn -0.464597 -0.548113 0.695501 +vn 0.039999 -0.996795 -0.069281 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn -0.110944 -0.979858 0.166042 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.551819 -0.625315 0.551794 +vn -0.121608 -0.979857 0.158406 +vn -0.475140 -0.625305 0.619061 +vn -0.551523 -0.548295 0.628645 +vn 0.048715 -0.996795 -0.063453 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn -0.131702 -0.979863 0.150080 +vn -0.141203 -0.979865 0.141164 +vn -0.848748 -0.198912 0.489960 +vn -0.675893 -0.625315 0.390065 +vn -0.695513 -0.548117 0.464574 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.619082 -0.625304 0.475112 +vn -0.141203 -0.979865 0.141164 +vn -0.551819 -0.625315 0.551794 +vn -0.628661 -0.548296 0.551504 +vn 0.056577 -0.996795 -0.056559 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn -0.150116 -0.979863 0.131661 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.675893 -0.625315 0.390065 +vn -0.158439 -0.979857 0.121565 +vn -0.619082 -0.625304 0.475112 +vn -0.695513 -0.548117 0.464574 +vn 0.063469 -0.996795 -0.048696 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn -0.166073 -0.979858 0.110900 +vn -0.172949 -0.979863 0.099784 +vn -0.959759 -0.214953 0.180714 +vn -0.972486 0.075824 0.220276 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.787262 -0.610234 0.088501 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.720921 -0.625312 0.298759 +vn -0.172949 -0.979863 0.099784 +vn -0.675893 -0.625315 0.390065 +vn -0.749983 -0.548375 0.369880 +vn 0.069293 -0.996795 -0.039977 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn -0.179081 -0.979865 0.088293 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.787262 -0.610234 0.088501 +vn -0.184475 -0.979861 0.076425 +vn -0.720921 -0.625312 0.298759 +vn -0.792052 -0.548040 0.268898 +vn 0.073908 -0.996795 -0.030617 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn -0.189113 -0.979856 0.064178 +vn -0.217514 -0.975719 0.025702 +vn -0.059975 -0.994232 0.088919 +vn 0.079340 -0.996763 -0.012975 +vn -0.217514 -0.975719 0.025702 +vn 0.003582 0.119290 0.992853 +vn -0.493340 0.119288 0.861618 +vn 0.003282 0.112908 0.993600 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn -0.494767 0.102956 0.862905 +vn 0.500192 0.089907 0.861234 +vn 0.499945 0.102956 0.859916 +vn 0.002990 0.102958 0.994681 +vn 0.522059 0.054243 0.851183 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.002546 0.089909 0.995947 +vn -0.495785 0.089908 0.863779 +vn 0.499657 0.112906 0.858834 +vn 0.499543 0.119288 0.858037 +vn 0.003582 0.119290 0.992853 +vn 0.499945 0.102956 0.859916 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.003282 0.112908 0.993600 +vn -0.493974 0.112906 0.862115 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.994681 0.102958 0.002990 +vn -0.495785 0.089908 0.863779 +vn -0.494767 0.102956 0.862905 +vn -0.859917 0.102956 0.499943 +vn -0.520588 0.054246 0.852083 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.861235 0.089907 0.500190 +vn -0.995947 0.089909 0.002546 +vn -0.493974 0.112906 0.862115 +vn -0.493340 0.119288 0.861618 +vn -0.858038 0.119288 0.499541 +vn -0.494767 0.102956 0.862905 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.858835 0.112906 0.499655 +vn -0.993600 0.112908 0.003282 +vn 0.860140 0.138592 0.490867 +vn 0.499499 0.138592 0.855157 +vn 0.860102 0.137445 0.491258 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.499366 0.128646 0.856787 +vn 0.992193 0.124653 -0.003810 +vn 0.991682 0.128649 -0.004054 +vn 0.860841 0.128646 0.492344 +vn 0.992853 0.119290 -0.003582 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.861162 0.124651 0.492811 +vn 0.499410 0.124651 0.857352 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.499299 0.134937 0.855858 +vn 0.991220 0.132159 -0.004236 +vn 0.990844 0.134939 -0.004460 +vn 0.860318 0.134936 0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.860531 0.132157 0.491956 +vn 0.499292 0.132157 0.856295 +vn 0.990337 0.138595 -0.004983 +vn 0.860140 0.138592 0.490867 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.860102 0.137445 0.491258 +vn 0.499269 0.137445 0.855476 +vn -0.857353 0.124650 0.499408 +vn -0.856788 0.128646 0.499364 +vn -0.991682 0.128649 0.004054 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn -0.492346 0.128646 0.860840 +vn 0.499410 0.124651 0.857352 +vn 0.499366 0.128646 0.856787 +vn 0.004054 0.128649 0.991682 +vn 0.499543 0.119288 0.858037 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.003810 0.124653 0.992193 +vn -0.492814 0.124651 0.861160 +vn -0.492814 0.124651 0.861160 +vn -0.492346 0.128646 0.860840 +vn -0.856788 0.128646 0.499364 +vn -0.493340 0.119288 0.861618 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.857353 0.124650 0.499408 +vn -0.992193 0.124653 0.003810 +vn 0.004983 0.138595 0.990337 +vn -0.490869 0.138592 0.860139 +vn 0.004625 0.137448 0.990498 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn -0.491576 0.134936 0.860317 +vn 0.499292 0.132157 0.856295 +vn 0.499299 0.134937 0.855858 +vn 0.004460 0.134939 0.990844 +vn 0.499366 0.128646 0.856787 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.004236 0.132159 0.991220 +vn -0.491957 0.132157 0.860530 +vn 0.499499 0.138592 0.855157 +vn 0.004983 0.138595 0.990337 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.004625 0.137448 0.990498 +vn -0.491260 0.137445 0.860100 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.990844 0.134939 0.004460 +vn -0.491957 0.132157 0.860530 +vn -0.491576 0.134936 0.860317 +vn -0.855859 0.134936 0.499297 +vn -0.492346 0.128646 0.860840 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.856296 0.132157 0.499291 +vn -0.991220 0.132159 0.004236 +vn -0.490869 0.138592 0.860139 +vn -0.855158 0.138592 0.499497 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.855477 0.137445 0.499267 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.990498 0.137448 0.004625 +vn -0.855477 0.137445 0.499267 +vn 0.990337 0.138595 -0.004983 +vn 0.990498 0.137448 -0.004625 +vn 0.855477 0.137445 -0.499267 +vn 0.992853 0.119290 -0.003582 +vn 0.993600 0.112908 -0.003282 +vn 0.858835 0.112906 -0.499655 +vn -0.499543 0.119288 -0.858037 +vn -0.499657 0.112906 -0.858834 +vn -0.862116 0.112906 -0.493972 +vn -0.679581 0.085468 -0.728605 +vn -0.865986 0.007573 -0.500011 +vn -0.864783 0.062737 -0.498211 +vn -0.864783 0.062737 -0.498211 +vn -0.559013 0.035015 -0.828420 +vn -0.679581 0.085468 -0.728605 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.998818 0.048476 0.003588 +vn -0.864783 0.062737 -0.498211 +vn -0.915190 -0.136671 -0.379143 +vn -0.946638 -0.198907 -0.253600 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.865986 0.007573 -0.500011 +vn -0.915190 -0.136671 -0.379143 +vn -0.982121 -0.136787 -0.129332 +vn -0.974045 -0.216081 0.067421 +vn -0.998818 0.048476 0.003588 +vn -0.998818 0.048476 0.003588 +vn -0.970776 0.085464 -0.224254 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.773684 -0.625316 -0.101943 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.834536 -0.548214 -0.054865 +vn -0.774567 -0.626221 0.088845 +vn -0.974045 -0.216081 0.067421 +vn -0.974045 -0.216081 0.067421 +vn -0.982121 -0.136787 -0.129332 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.197953 -0.979864 -0.026106 +vn -0.199250 -0.979861 -0.013125 +vn -0.834536 -0.548214 -0.054865 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.059975 -0.994232 0.088919 +vn -0.197953 -0.979864 -0.026106 +vn 0.079314 -0.996795 0.010461 +vn 0.079824 -0.996795 0.005260 +vn -0.753817 -0.625309 -0.201863 +vn -0.192889 -0.979859 -0.051676 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.195829 -0.979864 -0.038953 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn 0.079314 -0.996795 0.010461 +vn -0.192889 -0.979859 -0.051676 +vn 0.077272 -0.996795 0.020703 +vn 0.078460 -0.996795 0.015609 +vn -0.749973 -0.548375 -0.369898 +vn -0.720908 -0.625314 -0.298787 +vn -0.915190 -0.136671 -0.379143 +vn -0.915190 -0.136671 -0.379143 +vn -0.848748 -0.198912 -0.489960 +vn -0.749973 -0.548375 -0.369898 +vn -0.792045 -0.548040 -0.268918 +vn -0.753817 -0.625309 -0.201863 +vn -0.946638 -0.198907 -0.253600 +vn -0.946638 -0.198907 -0.253600 +vn -0.915190 -0.136671 -0.379143 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.184454 -0.979861 -0.076474 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn 0.077272 -0.996795 0.020703 +vn -0.184454 -0.979861 -0.076474 +vn 0.073898 -0.996795 0.030640 +vn 0.075746 -0.996795 0.025730 +vn -0.675878 -0.625313 -0.390093 +vn -0.172924 -0.979863 -0.099831 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.179057 -0.979865 -0.088341 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn 0.073898 -0.996795 0.030640 +vn -0.172924 -0.979863 -0.099831 +vn 0.069281 -0.996795 0.039999 +vn 0.071742 -0.996795 0.035397 +vn -0.559013 0.035015 -0.828420 +vn -0.489963 -0.198913 -0.848746 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.679581 0.085468 -0.728605 +vn -0.559013 0.035015 -0.828420 +vn -0.785908 -0.136554 -0.603077 +vn -0.848748 -0.198912 -0.489960 +vn -0.865986 0.007573 -0.500011 +vn -0.865986 0.007573 -0.500011 +vn -0.679581 0.085468 -0.728605 +vn -0.785908 -0.136554 -0.603077 +vn -0.628648 -0.548296 -0.551520 +vn -0.619062 -0.625306 -0.475137 +vn -0.785908 -0.136554 -0.603077 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.628648 -0.548296 -0.551520 +vn -0.695502 -0.548117 -0.464591 +vn -0.675878 -0.625313 -0.390093 +vn -0.848748 -0.198912 -0.489960 +vn -0.695502 -0.548117 -0.464591 +vn -0.848748 -0.198912 -0.489960 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.158405 -0.979857 -0.121607 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn 0.069281 -0.996795 0.039999 +vn -0.158405 -0.979857 -0.121607 +vn 0.063454 -0.996795 0.048715 +vn 0.066515 -0.996795 0.044445 +vn -0.551796 -0.625317 -0.551816 +vn -0.141165 -0.979865 -0.141202 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.150082 -0.979862 -0.131702 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn 0.063454 -0.996795 0.048715 +vn -0.141165 -0.979865 -0.141202 +vn 0.056560 -0.996795 0.056577 +vn 0.060129 -0.996795 0.052767 +vn -0.464580 -0.548113 -0.695513 +vn -0.475115 -0.625305 -0.619080 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.489963 -0.198913 -0.848746 +vn -0.464580 -0.548113 -0.695513 +vn -0.551508 -0.548294 -0.628659 +vn -0.551796 -0.625317 -0.551816 +vn -0.692977 -0.198918 -0.692975 +vn -0.551508 -0.548294 -0.628659 +vn -0.692977 -0.198918 -0.692975 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.121566 -0.979857 -0.158438 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn 0.056560 -0.996795 0.056577 +vn -0.121566 -0.979857 -0.158438 +vn 0.048696 -0.996795 0.063468 +vn 0.052748 -0.996795 0.060144 +vn -0.390067 -0.625315 -0.675892 +vn -0.099785 -0.979863 -0.172949 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.110900 -0.979858 -0.166071 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn 0.048696 -0.996795 0.063468 +vn -0.099785 -0.979863 -0.172949 +vn 0.039978 -0.996795 0.069293 +vn 0.044424 -0.996795 0.066528 +vn -0.499945 0.102956 -0.859916 +vn -0.500192 0.089907 -0.861234 +vn -0.863780 0.089908 -0.495782 +vn -0.862907 0.102956 -0.494765 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.998889 0.047128 0.000794 +vn -0.500192 0.089907 -0.861234 +vn -0.522059 0.054243 -0.851183 +vn -0.864783 0.062737 -0.498211 +vn -0.861619 0.119288 -0.493338 +vn -0.862116 0.112906 -0.493972 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.994681 0.102958 0.002990 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.862907 0.102956 -0.494765 +vn 0.863839 0.062737 -0.499846 +vn 0.998889 0.047128 -0.000794 +vn 0.998507 0.054619 0.000000 +vn 0.863839 0.062737 -0.499846 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 -0.224254 +vn 0.520588 0.054246 -0.852083 +vn 0.559013 0.035015 -0.828420 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn 0.520588 0.054246 -0.852083 +vn -0.224256 0.085466 -0.970775 +vn -0.559013 0.035015 -0.828420 +vn -0.522059 0.054243 -0.851183 +vn -0.522059 0.054243 -0.851183 +vn -0.000000 0.054620 -0.998507 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.253603 -0.198906 -0.946637 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn -0.379146 -0.136670 -0.915188 +vn -0.489963 -0.198913 -0.848746 +vn -0.559013 0.035015 -0.828420 +vn -0.379146 -0.136670 -0.915188 +vn -0.559013 0.035015 -0.828420 +vn -0.224256 0.085466 -0.970775 +vn -0.268901 -0.548039 -0.792052 +vn -0.298761 -0.625313 -0.720920 +vn -0.379146 -0.136670 -0.915188 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.369884 -0.548374 -0.749982 +vn -0.390067 -0.625315 -0.675892 +vn -0.489963 -0.198913 -0.848746 +vn -0.369884 -0.548374 -0.749982 +vn -0.489963 -0.198913 -0.848746 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.076426 -0.979861 -0.184474 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn 0.039978 -0.996795 0.069293 +vn -0.076426 -0.979861 -0.184474 +vn 0.030617 -0.996795 0.073907 +vn 0.035375 -0.996795 0.071753 +vn -0.201834 -0.625309 -0.753825 +vn -0.051625 -0.979859 -0.192902 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.064178 -0.979856 -0.189113 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn 0.030617 -0.996795 0.073907 +vn -0.051625 -0.979859 -0.192902 +vn 0.020680 -0.996795 0.077279 +vn 0.025707 -0.996795 0.075754 +vn -0.054845 -0.548214 -0.834538 +vn -0.101911 -0.625316 -0.773688 +vn -0.129333 -0.136787 -0.982121 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.163032 -0.548348 -0.820204 +vn -0.201834 -0.625309 -0.753825 +vn -0.253603 -0.198906 -0.946637 +vn -0.253603 -0.198906 -0.946637 +vn -0.129333 -0.136787 -0.982121 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.026053 -0.979864 -0.197959 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn 0.020680 -0.996795 0.077279 +vn -0.026053 -0.979864 -0.197959 +vn 0.010437 -0.996795 0.079315 +vn 0.015585 -0.996795 0.078466 +vn 0.000016 -0.625302 -0.780383 +vn 0.000027 -0.979855 -0.199708 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn -0.013072 -0.979860 -0.199255 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn 0.010437 -0.996795 0.079315 +vn 0.000027 -0.979855 -0.199708 +vn -0.000012 -0.996795 0.079997 +vn 0.005235 -0.996795 0.079826 +vn 0.379146 -0.136670 -0.915188 +vn 0.253603 -0.198906 -0.946637 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn 0.559013 0.035015 -0.828420 +vn 0.379146 -0.136670 -0.915188 +vn 0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.224256 0.085466 -0.970775 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.101942 -0.625316 -0.773684 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.054866 -0.548214 -0.834537 +vn 0.000016 -0.625302 -0.780383 +vn 0.000000 -0.198908 -0.980018 +vn 0.000000 -0.198908 -0.980018 +vn 0.129333 -0.136787 -0.982121 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.026105 -0.979864 -0.197952 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn -0.000012 -0.996795 0.079997 +vn 0.026105 -0.979864 -0.197952 +vn -0.010461 -0.996795 0.079312 +vn -0.005260 -0.996795 0.079825 +vn 0.201864 -0.625309 -0.753817 +vn 0.051676 -0.979859 -0.192887 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.038954 -0.979864 -0.195830 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn -0.010461 -0.996795 0.079312 +vn 0.051676 -0.979859 -0.192887 +vn -0.020704 -0.996795 0.077272 +vn -0.015609 -0.996795 0.078461 +vn 0.369902 -0.548374 -0.749972 +vn 0.298790 -0.625312 -0.720908 +vn 0.379146 -0.136670 -0.915188 +vn 0.379146 -0.136670 -0.915188 +vn 0.489963 -0.198913 -0.848746 +vn 0.369902 -0.548374 -0.749972 +vn 0.268920 -0.548039 -0.792045 +vn 0.201864 -0.625309 -0.753817 +vn 0.253603 -0.198906 -0.946637 +vn 0.253603 -0.198906 -0.946637 +vn 0.379146 -0.136670 -0.915188 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.076475 -0.979861 -0.184454 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn -0.020704 -0.996795 0.077272 +vn 0.076475 -0.979861 -0.184454 +vn -0.030640 -0.996795 0.073898 +vn -0.025730 -0.996795 0.075746 +vn 0.390094 -0.625314 -0.675876 +vn 0.099830 -0.979863 -0.172922 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.088341 -0.979865 -0.179057 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn -0.030640 -0.996795 0.073898 +vn 0.099830 -0.979863 -0.172922 +vn -0.039999 -0.996795 0.069281 +vn -0.035397 -0.996795 0.071742 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.679581 0.085468 -0.728605 +vn 0.679581 0.085468 -0.728605 +vn 0.559013 0.035015 -0.828420 +vn 0.863839 0.062737 -0.499846 +vn 0.785908 -0.136554 -0.603077 +vn 0.692977 -0.198918 -0.692975 +vn 0.679581 0.085468 -0.728605 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.865986 0.007573 -0.500011 +vn 0.603081 -0.136554 -0.785905 +vn 0.489963 -0.198913 -0.848746 +vn 0.559013 0.035015 -0.828420 +vn 0.559013 0.035015 -0.828420 +vn 0.679581 0.085468 -0.728605 +vn 0.603081 -0.136554 -0.785905 +vn 0.551523 -0.548295 -0.628645 +vn 0.475140 -0.625305 -0.619061 +vn 0.603081 -0.136554 -0.785905 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551523 -0.548295 -0.628645 +vn 0.464597 -0.548113 -0.695501 +vn 0.390094 -0.625314 -0.675876 +vn 0.489963 -0.198913 -0.848746 +vn 0.464597 -0.548113 -0.695501 +vn 0.489963 -0.198913 -0.848746 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.121608 -0.979857 -0.158406 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn -0.039999 -0.996795 0.069281 +vn 0.121608 -0.979857 -0.158406 +vn -0.048715 -0.996795 0.063453 +vn -0.044445 -0.996795 0.066514 +vn 0.551819 -0.625315 -0.551794 +vn 0.141203 -0.979865 -0.141164 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.131702 -0.979863 -0.150080 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn -0.048715 -0.996795 0.063453 +vn 0.141203 -0.979865 -0.141164 +vn -0.056577 -0.996795 0.056559 +vn -0.052767 -0.996795 0.060128 +vn 0.695513 -0.548117 -0.464574 +vn 0.619082 -0.625304 -0.475112 +vn 0.785908 -0.136554 -0.603077 +vn 0.785908 -0.136554 -0.603077 +vn 0.848748 -0.198912 -0.489960 +vn 0.695513 -0.548117 -0.464574 +vn 0.628661 -0.548296 -0.551504 +vn 0.551819 -0.625315 -0.551794 +vn 0.692977 -0.198918 -0.692975 +vn 0.628661 -0.548296 -0.551504 +vn 0.692977 -0.198918 -0.692975 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.158439 -0.979857 -0.121565 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn -0.056577 -0.996795 0.056559 +vn 0.158439 -0.979857 -0.121565 +vn -0.063469 -0.996795 0.048696 +vn -0.060145 -0.996795 0.052748 +vn 0.675893 -0.625315 -0.390065 +vn 0.172949 -0.979863 -0.099784 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.166073 -0.979858 -0.110900 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn -0.063469 -0.996795 0.048696 +vn 0.172949 -0.979863 -0.099784 +vn -0.069293 -0.996795 0.039977 +vn -0.066529 -0.996795 0.044425 +vn 0.998507 0.054619 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.970776 0.085464 -0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.915190 -0.136671 -0.379143 +vn 0.848748 -0.198912 -0.489960 +vn 0.865986 0.007573 -0.500011 +vn 0.915190 -0.136671 -0.379143 +vn 0.865986 0.007573 -0.500011 +vn 0.970776 0.085464 -0.224254 +vn 0.792052 -0.548040 -0.268898 +vn 0.720921 -0.625312 -0.298759 +vn 0.915190 -0.136671 -0.379143 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.749983 -0.548375 -0.369880 +vn 0.675893 -0.625315 -0.390065 +vn 0.848748 -0.198912 -0.489960 +vn 0.749983 -0.548375 -0.369880 +vn 0.848748 -0.198912 -0.489960 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.184475 -0.979861 -0.076425 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn -0.069293 -0.996795 0.039977 +vn 0.184475 -0.979861 -0.076425 +vn -0.073908 -0.996795 0.030617 +vn -0.071753 -0.996795 0.035375 +vn 0.753824 -0.625311 -0.201832 +vn 0.192902 -0.979859 -0.051624 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.189113 -0.979856 -0.064178 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn -0.073908 -0.996795 0.030617 +vn 0.192902 -0.979859 -0.051624 +vn -0.077279 -0.996795 0.020680 +vn -0.075754 -0.996795 0.025706 +vn 0.980018 -0.198907 0.000000 +vn 0.780383 -0.625302 0.000016 +vn 0.834538 -0.548214 -0.054844 +vn 0.834538 -0.548214 -0.054844 +vn 0.982121 -0.136787 -0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.820204 -0.548349 -0.163030 +vn 0.753824 -0.625311 -0.201832 +vn 0.946638 -0.198907 -0.253600 +vn 0.946638 -0.198907 -0.253600 +vn 0.982121 -0.136787 -0.129332 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.197959 -0.979864 -0.026053 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn -0.077279 -0.996795 0.020680 +vn 0.197959 -0.979864 -0.026053 +vn -0.079316 -0.996795 0.010437 +vn -0.078466 -0.996795 0.015585 +vn 0.780383 -0.625302 0.000016 +vn 0.199709 -0.979855 0.000026 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.199256 -0.979860 -0.013072 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn -0.079316 -0.996795 0.010437 +vn 0.199709 -0.979855 0.000026 +vn -0.079997 -0.996795 -0.000012 +vn -0.079827 -0.996795 0.005235 +vn 0.493340 0.119288 -0.861618 +vn 0.493974 0.112906 -0.862115 +vn -0.003282 0.112908 -0.993600 +vn 0.494767 0.102956 -0.862905 +vn 0.495785 0.089908 -0.863779 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn -0.002546 0.089909 -0.995947 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.522059 0.054243 -0.851183 +vn 0.495785 0.089908 -0.863779 +vn 0.520588 0.054246 -0.852083 +vn -0.000794 0.047128 -0.998889 +vn -0.003582 0.119290 -0.992853 +vn -0.003282 0.112908 -0.993600 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.499945 0.102956 -0.859916 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn -0.002990 0.102958 -0.994681 +vn 0.994681 0.102958 -0.002990 +vn 0.995947 0.089909 -0.002546 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.861235 0.089907 -0.500190 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.520588 0.054246 -0.852083 +vn 0.995947 0.089909 -0.002546 +vn 0.998889 0.047128 -0.000794 +vn 0.863839 0.062737 -0.499846 +vn 0.858038 0.119287 -0.499541 +vn 0.858835 0.112906 -0.499655 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.494767 0.102956 -0.862905 +vn 0.993600 0.112908 -0.003282 +vn 0.994681 0.102958 -0.002990 +vn 0.859917 0.102956 -0.499943 +vn -0.499499 0.138592 -0.855157 +vn -0.499269 0.137445 -0.855476 +vn -0.860102 0.137445 -0.491258 +vn -0.499366 0.128646 -0.856787 +vn -0.499410 0.124651 -0.857352 +vn -0.861162 0.124651 -0.492811 +vn -0.860841 0.128646 -0.492344 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.992853 0.119290 0.003582 +vn -0.499410 0.124651 -0.857352 +vn -0.499543 0.119288 -0.858037 +vn -0.861619 0.119288 -0.493338 +vn -0.499299 0.134937 -0.855858 +vn -0.499292 0.132157 -0.856295 +vn -0.860532 0.132157 -0.491955 +vn -0.860318 0.134936 -0.491574 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.991682 0.128649 0.004054 +vn -0.499292 0.132157 -0.856295 +vn -0.499366 0.128646 -0.856787 +vn -0.860841 0.128646 -0.492344 +vn -0.860140 0.138592 -0.490867 +vn -0.860102 0.137445 -0.491258 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.990844 0.134939 0.004460 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.860318 0.134936 -0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.992193 0.124653 -0.003810 +vn 0.857353 0.124650 -0.499408 +vn 0.492346 0.128646 -0.860840 +vn 0.492814 0.124651 -0.861160 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn -0.003810 0.124653 -0.992193 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.499543 0.119288 -0.858037 +vn 0.492814 0.124651 -0.861160 +vn 0.493340 0.119288 -0.861618 +vn -0.003582 0.119290 -0.992853 +vn 0.856788 0.128646 -0.499364 +vn 0.857353 0.124650 -0.499408 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.493340 0.119288 -0.861618 +vn 0.992193 0.124653 -0.003810 +vn 0.992853 0.119290 -0.003582 +vn 0.858038 0.119287 -0.499541 +vn 0.490869 0.138592 -0.860139 +vn 0.491260 0.137445 -0.860100 +vn -0.004625 0.137448 -0.990498 +vn 0.491576 0.134936 -0.860317 +vn 0.491957 0.132157 -0.860530 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn -0.004236 0.132159 -0.991220 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.499366 0.128646 -0.856787 +vn 0.491957 0.132157 -0.860530 +vn 0.492346 0.128646 -0.860840 +vn -0.004054 0.128649 -0.991682 +vn -0.004983 0.138595 -0.990337 +vn -0.004625 0.137448 -0.990498 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.499299 0.134937 -0.855858 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn -0.004460 0.134939 -0.990844 +vn 0.990844 0.134939 -0.004460 +vn 0.991220 0.132159 -0.004236 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.856296 0.132157 -0.499291 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.492346 0.128646 -0.860840 +vn 0.991220 0.132159 -0.004236 +vn 0.991682 0.128649 -0.004054 +vn 0.856788 0.128646 -0.499364 +vn 0.855158 0.138592 -0.499497 +vn 0.855477 0.137445 -0.499267 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.491576 0.134936 -0.860317 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.855859 0.134936 -0.499297 +vn -0.992853 0.119290 0.003582 +vn -0.993600 0.112908 0.003282 +vn -0.858835 0.112906 0.499655 +vn 0.499543 0.119288 0.858037 +vn 0.499657 0.112906 0.858834 +vn 0.862116 0.112906 0.493972 +vn 0.679581 0.085468 0.728605 +vn 0.865986 0.007573 0.500011 +vn 0.864783 0.062737 0.498211 +vn 0.864783 0.062737 0.498211 +vn 0.559013 0.035015 0.828420 +vn 0.679581 0.085468 0.728605 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.864783 0.062737 0.498211 +vn 0.915190 -0.136671 0.379143 +vn 0.946638 -0.198907 0.253600 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.865986 0.007573 0.500011 +vn 0.915190 -0.136671 0.379143 +vn 0.982121 -0.136787 0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 0.224254 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.773684 -0.625316 0.101943 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.834536 -0.548215 0.054865 +vn 0.780383 -0.625302 0.000016 +vn 0.980018 -0.198907 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 0.129332 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.197953 -0.979864 0.026106 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn -0.079997 -0.996795 -0.000012 +vn 0.197953 -0.979864 0.026106 +vn -0.079314 -0.996795 -0.010461 +vn -0.079824 -0.996795 -0.005260 +vn 0.753817 -0.625309 0.201863 +vn 0.192889 -0.979859 0.051676 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.195829 -0.979864 0.038953 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn -0.079314 -0.996795 -0.010461 +vn 0.192889 -0.979859 0.051676 +vn -0.077272 -0.996795 -0.020703 +vn -0.078460 -0.996795 -0.015609 +vn 0.749973 -0.548375 0.369898 +vn 0.720908 -0.625314 0.298787 +vn 0.915190 -0.136671 0.379143 +vn 0.915190 -0.136671 0.379143 +vn 0.848748 -0.198912 0.489960 +vn 0.749973 -0.548375 0.369898 +vn 0.792045 -0.548040 0.268918 +vn 0.753817 -0.625309 0.201863 +vn 0.946638 -0.198907 0.253600 +vn 0.946638 -0.198907 0.253600 +vn 0.915190 -0.136671 0.379143 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.184454 -0.979861 0.076474 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn -0.077272 -0.996795 -0.020703 +vn 0.184454 -0.979861 0.076474 +vn -0.073898 -0.996795 -0.030640 +vn -0.075746 -0.996795 -0.025730 +vn 0.675878 -0.625313 0.390093 +vn 0.172924 -0.979863 0.099831 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.179057 -0.979865 0.088341 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn -0.073898 -0.996795 -0.030640 +vn 0.172924 -0.979863 0.099831 +vn -0.069281 -0.996795 -0.039999 +vn -0.071742 -0.996795 -0.035397 +vn 0.603081 -0.136554 0.785905 +vn 0.692977 -0.198918 0.692975 +vn 0.679581 0.085468 0.728605 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.559013 0.035015 0.828420 +vn 0.785908 -0.136554 0.603077 +vn 0.848748 -0.198912 0.489960 +vn 0.865986 0.007573 0.500011 +vn 0.865986 0.007573 0.500011 +vn 0.679581 0.085468 0.728605 +vn 0.785908 -0.136554 0.603077 +vn 0.628648 -0.548296 0.551520 +vn 0.619062 -0.625306 0.475137 +vn 0.785908 -0.136554 0.603077 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.628648 -0.548296 0.551520 +vn 0.695502 -0.548117 0.464591 +vn 0.675878 -0.625313 0.390093 +vn 0.848748 -0.198912 0.489960 +vn 0.695502 -0.548117 0.464591 +vn 0.848748 -0.198912 0.489960 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.158405 -0.979857 0.121607 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn -0.069281 -0.996795 -0.039999 +vn 0.158405 -0.979857 0.121607 +vn -0.063454 -0.996795 -0.048715 +vn -0.066515 -0.996795 -0.044445 +vn 0.551796 -0.625317 0.551816 +vn 0.141165 -0.979865 0.141202 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.150082 -0.979862 0.131702 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn -0.063454 -0.996795 -0.048715 +vn 0.141165 -0.979865 0.141202 +vn -0.056560 -0.996795 -0.056577 +vn -0.060129 -0.996795 -0.052767 +vn 0.464580 -0.548113 0.695513 +vn 0.475115 -0.625305 0.619080 +vn 0.603081 -0.136554 0.785905 +vn 0.603081 -0.136554 0.785905 +vn 0.489963 -0.198913 0.848746 +vn 0.464580 -0.548113 0.695513 +vn 0.551508 -0.548294 0.628659 +vn 0.551796 -0.625317 0.551816 +vn 0.692977 -0.198918 0.692975 +vn 0.551508 -0.548294 0.628659 +vn 0.692977 -0.198918 0.692975 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.121566 -0.979857 0.158438 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn -0.056560 -0.996795 -0.056577 +vn 0.121566 -0.979857 0.158438 +vn -0.048696 -0.996795 -0.063468 +vn -0.052748 -0.996795 -0.060144 +vn 0.390067 -0.625315 0.675892 +vn 0.099785 -0.979863 0.172949 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.110900 -0.979858 0.166071 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn -0.048696 -0.996795 -0.063468 +vn 0.099785 -0.979863 0.172949 +vn -0.039978 -0.996795 -0.069293 +vn -0.044424 -0.996795 -0.066528 +vn 0.499945 0.102956 0.859916 +vn 0.500192 0.089907 0.861234 +vn 0.863780 0.089908 0.495782 +vn 0.862907 0.102956 0.494765 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.998889 0.047128 -0.000794 +vn 0.500192 0.089907 0.861234 +vn 0.522059 0.054243 0.851183 +vn 0.864783 0.062737 0.498211 +vn 0.861619 0.119288 0.493338 +vn 0.862116 0.112906 0.493972 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.994681 0.102958 -0.002990 +vn 0.499657 0.112906 0.858834 +vn 0.499945 0.102956 0.859916 +vn 0.862907 0.102956 0.494765 +vn -0.863839 0.062737 0.499846 +vn -0.998889 0.047128 0.000794 +vn -0.998818 0.048476 0.003588 +vn -0.863839 0.062737 0.499846 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.520588 0.054246 0.852083 +vn -0.559013 0.035015 0.828420 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn -0.520588 0.054246 0.852083 +vn 0.224256 0.085466 0.970775 +vn 0.559013 0.035015 0.828420 +vn 0.522059 0.054243 0.851183 +vn 0.522059 0.054243 0.851183 +vn 0.000000 0.054620 0.998507 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.253603 -0.198906 0.946637 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn 0.379146 -0.136670 0.915188 +vn 0.489963 -0.198913 0.848746 +vn 0.559013 0.035015 0.828420 +vn 0.379146 -0.136670 0.915188 +vn 0.559013 0.035015 0.828420 +vn 0.224256 0.085466 0.970775 +vn 0.268901 -0.548039 0.792052 +vn 0.298761 -0.625313 0.720920 +vn 0.379146 -0.136670 0.915188 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.369884 -0.548374 0.749982 +vn 0.390067 -0.625315 0.675892 +vn 0.489963 -0.198913 0.848746 +vn 0.369884 -0.548374 0.749982 +vn 0.489963 -0.198913 0.848746 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.076426 -0.979861 0.184474 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn -0.039978 -0.996795 -0.069293 +vn 0.076426 -0.979861 0.184474 +vn -0.030617 -0.996795 -0.073907 +vn -0.035375 -0.996795 -0.071753 +vn 0.201834 -0.625309 0.753825 +vn 0.051625 -0.979859 0.192902 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.064178 -0.979856 0.189113 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn -0.030617 -0.996795 -0.073907 +vn 0.051625 -0.979859 0.192902 +vn -0.020680 -0.996795 -0.077279 +vn -0.025707 -0.996795 -0.075754 +vn 0.054845 -0.548214 0.834538 +vn 0.101911 -0.625316 0.773688 +vn 0.129333 -0.136787 0.982121 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.163032 -0.548348 0.820204 +vn 0.201834 -0.625309 0.753825 +vn 0.253603 -0.198906 0.946637 +vn 0.253603 -0.198906 0.946637 +vn 0.129333 -0.136787 0.982121 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.026053 -0.979864 0.197959 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn -0.020680 -0.996795 -0.077279 +vn 0.026053 -0.979864 0.197959 +vn -0.010437 -0.996795 -0.079315 +vn -0.015585 -0.996795 -0.078466 +vn -0.000016 -0.625302 0.780383 +vn -0.000027 -0.979855 0.199708 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn 0.013072 -0.979860 0.199255 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn -0.010437 -0.996795 -0.079315 +vn -0.000027 -0.979855 0.199708 +vn 0.000012 -0.996795 -0.079997 +vn -0.005235 -0.996795 -0.079826 +vn -0.379146 -0.136670 0.915188 +vn -0.253603 -0.198906 0.946637 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn -0.559013 0.035015 0.828420 +vn -0.379146 -0.136670 0.915188 +vn -0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn -0.224256 0.085466 0.970775 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.101942 -0.625316 0.773684 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.054866 -0.548214 0.834537 +vn -0.000016 -0.625302 0.780383 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 -0.198908 0.980018 +vn -0.129333 -0.136787 0.982121 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.026105 -0.979864 0.197952 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn 0.000012 -0.996795 -0.079997 +vn -0.026105 -0.979864 0.197952 +vn 0.010461 -0.996795 -0.079312 +vn 0.005260 -0.996795 -0.079825 +vn -0.201864 -0.625309 0.753817 +vn -0.051676 -0.979859 0.192887 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.038954 -0.979864 0.195830 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn 0.010461 -0.996795 -0.079312 +vn -0.051676 -0.979859 0.192887 +vn 0.020704 -0.996795 -0.077272 +vn 0.015609 -0.996795 -0.078461 +vn -0.369902 -0.548374 0.749972 +vn -0.298790 -0.625312 0.720908 +vn -0.379146 -0.136670 0.915188 +vn -0.379146 -0.136670 0.915188 +vn -0.489963 -0.198913 0.848746 +vn -0.369902 -0.548374 0.749972 +vn -0.268920 -0.548039 0.792045 +vn -0.201864 -0.625309 0.753817 +vn -0.253603 -0.198906 0.946637 +vn -0.253603 -0.198906 0.946637 +vn -0.379146 -0.136670 0.915188 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.076475 -0.979861 0.184454 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn 0.020704 -0.996795 -0.077272 +vn -0.076475 -0.979861 0.184454 +vn 0.030640 -0.996795 -0.073898 +vn 0.025730 -0.996795 -0.075746 +vn -0.390094 -0.625314 0.675876 +vn -0.099830 -0.979863 0.172922 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.088341 -0.979865 0.179057 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn 0.030640 -0.996795 -0.073898 +vn -0.099830 -0.979863 0.172922 +vn 0.039999 -0.996795 -0.069281 +vn 0.035397 -0.996795 -0.071742 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.679581 0.085468 0.728605 +vn -0.679581 0.085468 0.728605 +vn -0.559013 0.035015 0.828420 +vn -0.863839 0.062737 0.499846 +vn -0.785908 -0.136554 0.603077 +vn -0.692977 -0.198918 0.692975 +vn -0.679581 0.085468 0.728605 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.865986 0.007573 0.500011 +vn -0.603081 -0.136554 0.785905 +vn -0.489963 -0.198913 0.848746 +vn -0.559013 0.035015 0.828420 +vn -0.559013 0.035015 0.828420 +vn -0.679581 0.085468 0.728605 +vn -0.603081 -0.136554 0.785905 +vn -0.551523 -0.548295 0.628645 +vn -0.475140 -0.625305 0.619061 +vn -0.603081 -0.136554 0.785905 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551523 -0.548295 0.628645 +vn -0.464597 -0.548113 0.695501 +vn -0.390094 -0.625314 0.675876 +vn -0.489963 -0.198913 0.848746 +vn -0.464597 -0.548113 0.695501 +vn -0.489963 -0.198913 0.848746 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.121608 -0.979857 0.158406 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn 0.039999 -0.996795 -0.069281 +vn -0.121608 -0.979857 0.158406 +vn 0.048715 -0.996795 -0.063453 +vn 0.044445 -0.996795 -0.066514 +vn -0.551819 -0.625315 0.551794 +vn -0.141203 -0.979865 0.141164 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.131702 -0.979863 0.150080 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn 0.048715 -0.996795 -0.063453 +vn -0.141203 -0.979865 0.141164 +vn 0.056577 -0.996795 -0.056559 +vn 0.052767 -0.996795 -0.060128 +vn -0.695513 -0.548117 0.464574 +vn -0.619082 -0.625304 0.475112 +vn -0.785908 -0.136554 0.603077 +vn -0.785908 -0.136554 0.603077 +vn -0.848748 -0.198912 0.489960 +vn -0.695513 -0.548117 0.464574 +vn -0.628661 -0.548296 0.551504 +vn -0.551819 -0.625315 0.551794 +vn -0.692977 -0.198918 0.692975 +vn -0.628661 -0.548296 0.551504 +vn -0.692977 -0.198918 0.692975 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.158439 -0.979857 0.121565 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn 0.056577 -0.996795 -0.056559 +vn -0.158439 -0.979857 0.121565 +vn 0.063469 -0.996795 -0.048696 +vn 0.060145 -0.996795 -0.052748 +vn -0.675893 -0.625315 0.390065 +vn -0.172949 -0.979863 0.099784 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.166073 -0.979858 0.110900 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn 0.063469 -0.996795 -0.048696 +vn -0.172949 -0.979863 0.099784 +vn 0.069293 -0.996795 -0.039977 +vn 0.066529 -0.996795 -0.044425 +vn -0.998818 0.048476 0.003588 +vn -0.974045 -0.216081 0.067421 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.848748 -0.198912 0.489960 +vn -0.865986 0.007573 0.500011 +vn -0.915190 -0.136671 0.379143 +vn -0.865986 0.007573 0.500011 +vn -0.972486 0.075824 0.220276 +vn -0.792052 -0.548040 0.268898 +vn -0.720921 -0.625312 0.298759 +vn -0.915190 -0.136671 0.379143 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.749983 -0.548375 0.369880 +vn -0.675893 -0.625315 0.390065 +vn -0.848748 -0.198912 0.489960 +vn -0.749983 -0.548375 0.369880 +vn -0.848748 -0.198912 0.489960 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.184475 -0.979861 0.076425 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn 0.069293 -0.996795 -0.039977 +vn -0.184475 -0.979861 0.076425 +vn 0.073908 -0.996795 -0.030617 +vn 0.071753 -0.996795 -0.035375 +vn -0.787262 -0.610234 0.088501 +vn -0.217514 -0.975719 0.025702 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.189113 -0.979856 0.064178 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn 0.073908 -0.996795 -0.030617 +vn -0.217514 -0.975719 0.025702 +vn 0.079340 -0.996763 -0.012975 +vn 0.075754 -0.996795 -0.025706 +vn -0.959759 -0.214953 0.180714 +vn -0.974045 -0.216081 0.067421 +vn -0.774567 -0.626221 0.088845 +vn -0.787262 -0.610234 0.088501 +vn -0.959759 -0.214953 0.180714 +vn -0.059975 -0.994232 0.088919 +vn -0.217514 -0.975719 0.025702 +vn -0.787262 -0.610234 0.088501 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.059975 -0.994232 0.088919 +vn -0.959759 -0.214953 0.180714 +vn -0.959759 -0.214953 0.180714 +vn -0.774567 -0.626221 0.088845 +vn -0.195626 -0.976106 0.094593 +vn -0.493340 0.119288 0.861618 +vn -0.493974 0.112906 0.862115 +vn 0.003282 0.112908 0.993600 +vn -0.494767 0.102956 0.862905 +vn -0.495785 0.089908 0.863779 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn 0.002546 0.089909 0.995947 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.522059 0.054243 0.851183 +vn -0.495785 0.089908 0.863779 +vn -0.520588 0.054246 0.852083 +vn 0.000794 0.047128 0.998889 +vn 0.003582 0.119290 0.992853 +vn 0.003282 0.112908 0.993600 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.499945 0.102956 0.859916 +vn -0.493974 0.112906 0.862115 +vn -0.494767 0.102956 0.862905 +vn 0.002990 0.102958 0.994681 +vn -0.994681 0.102958 0.002990 +vn -0.995947 0.089909 0.002546 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.861235 0.089907 0.500190 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.520588 0.054246 0.852083 +vn -0.995947 0.089909 0.002546 +vn -0.998889 0.047128 0.000794 +vn -0.863839 0.062737 0.499846 +vn -0.858038 0.119288 0.499541 +vn -0.858835 0.112906 0.499655 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.494767 0.102956 0.862905 +vn -0.993600 0.112908 0.003282 +vn -0.994681 0.102958 0.002990 +vn -0.859917 0.102956 0.499943 +vn 0.499499 0.138592 0.855157 +vn 0.499269 0.137445 0.855476 +vn 0.860102 0.137445 0.491258 +vn 0.499366 0.128646 0.856787 +vn 0.499410 0.124651 0.857352 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.861162 0.124651 0.492811 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.992853 0.119290 -0.003582 +vn 0.499410 0.124651 0.857352 +vn 0.499543 0.119288 0.858037 +vn 0.861619 0.119288 0.493338 +vn 0.499299 0.134937 0.855858 +vn 0.499292 0.132157 0.856295 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.860531 0.132157 0.491956 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.991682 0.128649 -0.004054 +vn 0.499292 0.132157 0.856295 +vn 0.499366 0.128646 0.856787 +vn 0.860841 0.128646 0.492344 +vn 0.860140 0.138592 0.490867 +vn 0.860102 0.137445 0.491258 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.990844 0.134939 -0.004460 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.860318 0.134936 0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.992193 0.124653 0.003810 +vn -0.857353 0.124650 0.499408 +vn -0.492346 0.128646 0.860840 +vn -0.492814 0.124651 0.861160 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn 0.003810 0.124653 0.992193 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.499543 0.119288 0.858037 +vn -0.492814 0.124651 0.861160 +vn -0.493340 0.119288 0.861618 +vn 0.003582 0.119290 0.992853 +vn -0.856788 0.128646 0.499364 +vn -0.857353 0.124650 0.499408 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.493340 0.119288 0.861618 +vn -0.992193 0.124653 0.003810 +vn -0.992853 0.119290 0.003582 +vn -0.858038 0.119288 0.499541 +vn -0.490869 0.138592 0.860139 +vn -0.491260 0.137445 0.860100 +vn 0.004625 0.137448 0.990498 +vn -0.491576 0.134936 0.860317 +vn -0.491957 0.132157 0.860530 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn 0.004236 0.132159 0.991220 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.499366 0.128646 0.856787 +vn -0.491957 0.132157 0.860530 +vn -0.492346 0.128646 0.860840 +vn 0.004054 0.128649 0.991682 +vn 0.004983 0.138595 0.990337 +vn 0.004625 0.137448 0.990498 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.499299 0.134937 0.855858 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn 0.004460 0.134939 0.990844 +vn -0.990844 0.134939 0.004460 +vn -0.991220 0.132159 0.004236 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.856296 0.132157 0.499291 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.492346 0.128646 0.860840 +vn -0.991220 0.132159 0.004236 +vn -0.991682 0.128649 0.004054 +vn -0.856788 0.128646 0.499364 +vn -0.855158 0.138592 0.499497 +vn -0.855477 0.137445 0.499267 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.491576 0.134936 0.860317 +vn -0.990498 0.137448 0.004625 +vn -0.990844 0.134939 0.004460 +vn -0.855859 0.134936 0.499297 +s off +g glass:revolvedSurface2 +usemtl initialShadingGroup +f 481/1/1 2/2/2 482/3/3 +f 260/4/4 3/5/5 261/6/6 +f 220/7/7 6/8/8 221/9/9 +f 81/10/10 7/11/11 83/12/12 +f 11/13/13 10/14/14 46/15/15 +f 13/16/16 9/17/17 11/13/18 +f 14/18/19 33/19/20 35/20/21 +f 15/21/22 18/22/23 19/23/24 +f 18/22/25 28/24/26 30/25/27 +f 19/23/28 22/26/29 23/27/30 +f 23/27/31 22/26/32 26/28/33 +f 25/29/34 21/30/35 23/27/36 +f 1/31/37 25/29/38 26/28/39 +f 24/32/40 26/28/41 27/33/42 +f 31/34/43 30/25/44 28/24/45 +f 27/33/46 22/26/47 30/25/48 +f 20/35/49 27/33/50 31/34/51 +f 29/36/52 31/34/53 32/37/54 +f 33/19/55 41/38/56 43/39/57 +f 35/20/58 36/40/59 38/41/60 +f 39/42/61 38/41/62 36/40/63 +f 32/37/64 28/24/65 38/41/66 +f 16/43/67 32/37/68 39/42/69 +f 37/44/70 39/42/71 40/45/72 +f 44/46/73 43/39/74 41/38/75 +f 40/45/76 36/40/77 43/39/78 +f 34/47/79 40/45/80 44/46/81 +f 42/48/82 44/46/83 45/49/84 +f 64/50/85 49/51/86 48/52/87 +f 48/52/88 49/51/89 51/53/90 +f 49/51/91 57/54/92 59/55/93 +f 51/53/94 52/56/95 54/57/96 +f 55/58/97 54/57/98 52/56/99 +f 45/49/100 41/38/101 54/57/102 +f 12/59/103 45/49/104 55/58/105 +f 53/60/106 55/58/107 56/61/108 +f 60/62/109 59/55/110 57/54/111 +f 56/61/112 52/56/113 59/55/114 +f 50/63/115 56/61/116 60/62/117 +f 58/64/118 60/62/119 61/65/120 +f 62/66/121 70/67/122 72/68/123 +f 64/50/124 65/69/125 67/70/126 +f 68/71/127 67/70/128 65/69/129 +f 61/65/130 57/54/131 67/70/132 +f 47/72/133 61/65/134 68/71/135 +f 66/73/136 68/71/137 69/74/138 +f 73/75/139 72/68/140 70/67/141 +f 69/74/142 65/69/143 72/68/144 +f 63/76/145 69/74/146 73/75/147 +f 71/77/148 73/75/149 74/78/150 +f 77/79/151 76/80/152 79/81/153 +f 78/82/154 75/83/155 77/79/156 +f 9/17/157 78/82/158 79/81/159 +f 11/13/160 79/81/161 80/84/162 +f 82/85/163 5/86/164 81/10/165 +f 75/83/166 82/85/167 83/12/168 +f 77/79/169 83/12/170 84/87/171 +f 181/88/172 150/89/173 149/90/174 +f 90/91/175 89/92/176 87/93/177 +f 10/14/178 89/92/179 90/91/180 +f 90/91/181 106/94/182 108/95/183 +f 92/96/184 93/97/185 95/98/186 +f 93/97/187 101/99/188 103/100/189 +f 95/98/190 96/101/191 98/102/192 +f 99/103/193 98/102/194 96/101/195 +f 74/78/196 70/67/197 98/102/198 +f 8/104/199 74/78/200 99/103/201 +f 97/105/202 99/103/203 100/106/204 +f 104/107/205 103/100/206 101/99/207 +f 100/106/208 96/101/209 103/100/210 +f 94/108/211 100/106/212 104/107/213 +f 102/109/214 104/107/215 105/110/216 +f 106/94/217 114/111/218 116/112/219 +f 108/95/220 109/113/221 111/114/222 +f 112/115/223 111/114/224 109/113/225 +f 105/110/226 101/99/227 111/114/228 +f 91/116/229 105/110/230 112/115/231 +f 110/117/232 112/115/233 113/118/234 +f 117/119/235 116/112/236 114/111/237 +f 113/118/238 109/113/239 116/112/240 +f 107/120/241 113/118/242 117/119/243 +f 115/121/244 117/119/245 118/122/246 +f 119/123/247 135/124/248 137/125/249 +f 121/126/250 122/127/251 124/128/252 +f 122/127/253 130/129/254 132/130/255 +f 124/128/256 125/131/257 127/132/258 +f 128/133/259 127/132/260 125/131/261 +f 118/122/262 114/111/263 127/132/264 +f 88/134/265 118/122/266 128/133/267 +f 126/135/268 128/133/269 129/136/270 +f 133/137/271 132/130/272 130/129/273 +f 129/136/274 125/131/275 132/130/276 +f 123/138/277 129/136/278 133/137/279 +f 131/139/280 133/137/281 134/140/282 +f 135/124/283 143/141/284 145/142/285 +f 137/125/286 138/143/287 140/144/288 +f 141/145/289 140/144/290 138/143/291 +f 134/140/292 130/129/293 140/144/294 +f 120/146/295 134/140/296 141/145/297 +f 139/147/298 141/145/299 142/148/300 +f 146/149/301 145/142/302 143/141/303 +f 142/148/304 138/143/305 145/142/306 +f 136/150/307 142/148/308 146/149/309 +f 144/151/310 146/149/311 147/152/312 +f 119/123/313 87/93/314 149/90/315 +f 150/89/316 166/153/317 168/154/318 +f 152/155/319 153/156/320 155/157/321 +f 153/156/322 161/158/323 163/159/324 +f 155/157/325 156/160/326 158/161/327 +f 159/162/328 158/161/329 156/160/330 +f 147/152/331 143/141/332 158/161/333 +f 86/163/334 147/152/335 159/162/336 +f 157/164/337 159/162/338 160/165/339 +f 164/166/340 163/159/341 161/158/342 +f 160/165/343 156/160/344 163/159/345 +f 154/167/346 160/165/347 164/166/348 +f 162/168/349 164/166/350 165/169/351 +f 166/153/352 174/170/353 176/171/354 +f 168/154/355 169/172/356 171/173/357 +f 172/174/358 171/173/359 169/172/360 +f 165/169/361 161/158/362 171/173/363 +f 151/175/364 165/169/365 172/174/366 +f 170/176/367 172/174/368 173/177/369 +f 177/178/370 176/171/371 174/170/372 +f 173/177/373 169/172/374 176/171/375 +f 167/179/376 173/177/377 177/178/378 +f 175/180/379 177/178/380 178/181/381 +f 197/182/382 182/183/383 181/88/384 +f 181/88/385 182/183/386 184/184/387 +f 182/183/388 190/185/389 192/186/390 +f 184/184/391 185/187/392 187/188/393 +f 188/189/394 187/188/395 185/187/396 +f 178/181/397 174/170/398 187/188/399 +f 148/190/400 178/181/401 188/189/402 +f 186/191/403 188/189/404 189/192/405 +f 193/193/406 192/186/407 190/185/408 +f 189/192/409 185/187/410 192/186/411 +f 183/194/412 189/192/413 193/193/414 +f 191/195/415 193/193/416 194/196/417 +f 205/197/418 198/198/419 197/182/420 +f 197/182/421 198/198/422 200/199/423 +f 201/200/424 200/199/425 198/198/426 +f 194/196/427 190/185/428 200/199/429 +f 180/201/430 194/196/431 201/200/432 +f 199/202/433 201/200/434 202/203/435 +f 206/204/436 205/197/437 203/205/438 +f 202/203/439 198/198/440 205/197/441 +f 196/206/442 202/203/443 206/204/444 +f 204/207/445 206/204/446 207/208/447 +f 213/209/448 208/210/449 214/211/450 +f 211/212/451 210/213/452 209/214/453 +f 80/84/454 76/80/455 210/213/456 +f 10/14/457 80/84/458 211/212/459 +f 89/92/460 211/212/461 212/215/462 +f 7/11/463 213/209/464 84/87/465 +f 76/80/466 84/87/467 214/211/468 +f 210/213/469 214/211/470 215/216/471 +f 218/217/472 217/218/473 216/219/474 +f 212/215/475 209/214/476 217/218/477 +f 87/93/478 212/215/479 218/217/480 +f 149/90/481 218/217/482 219/220/483 +f 208/210/484 220/7/485 215/216/486 +f 209/214/487 215/216/488 221/9/489 +f 217/218/490 221/9/491 222/221/492 +f 236/222/493 223/223/494 238/224/495 +f 226/225/496 225/226/497 228/227/498 +f 227/228/499 224/229/500 226/225/501 +f 5/86/502 227/228/503 228/227/504 +f 81/10/505 228/227/506 229/230/507 +f 232/231/508 231/232/509 234/233/510 +f 233/234/511 230/235/512 232/231/513 +f 224/229/514 233/234/515 234/233/516 +f 226/225/517 234/233/518 235/236/519 +f 237/237/520 2/238/521 236/222/522 +f 230/235/523 237/237/524 238/224/525 +f 232/231/526 238/224/527 239/239/528 +f 246/240/529 245/241/530 240/242/531 +f 243/243/532 242/244/533 241/245/534 +f 229/230/535 225/226/536 242/244/537 +f 7/11/538 229/230/539 243/243/540 +f 213/209/541 243/243/542 244/246/543 +f 244/246/544 241/245/545 245/241/546 +f 208/210/547 244/246/548 246/240/549 +f 220/7/550 246/240/551 247/247/552 +f 253/248/553 248/249/554 254/250/555 +f 251/251/556 250/252/557 249/253/558 +f 235/236/559 231/232/560 250/252/561 +f 225/226/562 235/236/563 251/251/564 +f 242/244/565 251/251/566 252/254/567 +f 223/223/568 253/248/569 239/239/570 +f 231/232/571 239/239/572 254/250/573 +f 250/252/574 254/250/575 255/255/576 +f 258/256/577 257/257/578 256/258/579 +f 252/254/580 249/253/581 257/257/582 +f 241/245/583 252/254/584 258/256/585 +f 245/241/586 258/256/587 259/259/588 +f 248/249/589 260/4/590 255/255/591 +f 249/253/592 255/255/593 261/6/594 +f 257/257/595 261/6/596 262/260/597 +f 452/261/598 451/262/599 5/263/600 +f 330/264/601 264/265/602 331/266/603 +f 267/267/604 265/268/605 297/269/606 +f 179/270/607 85/271/608 267/267/609 +f 268/272/610 284/273/611 286/274/612 +f 270/275/613 271/276/614 273/277/615 +f 271/276/616 279/278/617 281/279/618 +f 273/277/619 274/280/620 276/281/621 +f 277/282/622 276/281/623 274/280/624 +f 207/208/625 203/205/626 276/281/627 +f 4/283/628 207/208/629 277/282/630 +f 275/284/631 277/282/632 278/285/633 +f 282/286/634 281/279/635 279/278/636 +f 278/285/637 274/280/638 281/279/639 +f 272/287/640 278/285/641 282/286/642 +f 280/288/643 282/286/644 283/289/645 +f 284/273/646 292/290/647 294/291/648 +f 286/274/649 287/292/650 289/293/651 +f 290/294/652 289/293/653 287/292/654 +f 283/289/655 279/278/656 289/293/657 +f 269/295/658 283/289/659 290/294/660 +f 288/296/661 290/294/662 291/297/663 +f 295/298/664 294/291/665 292/290/666 +f 291/297/667 287/292/668 294/291/669 +f 285/299/670 291/297/671 295/298/672 +f 293/300/673 295/298/674 296/301/675 +f 297/269/676 313/302/677 315/303/678 +f 299/304/679 300/305/680 302/306/681 +f 300/305/682 308/307/683 310/308/684 +f 302/306/685 303/309/686 305/310/687 +f 306/311/688 305/310/689 303/309/690 +f 296/301/691 292/290/692 305/310/693 +f 266/312/694 296/301/695 306/311/696 +f 304/313/697 306/311/698 307/314/699 +f 311/315/700 310/308/701 308/307/702 +f 307/314/703 303/309/704 310/308/705 +f 301/316/706 307/314/707 311/315/708 +f 309/317/709 311/315/710 312/318/711 +f 313/302/712 321/319/713 323/320/714 +f 315/303/715 316/321/716 318/322/717 +f 319/323/718 318/322/719 316/321/720 +f 312/318/721 308/307/722 318/322/723 +f 298/324/724 312/318/725 319/323/726 +f 317/325/727 319/323/728 320/326/729 +f 324/327/730 323/320/731 321/319/732 +f 320/326/733 316/321/734 323/320/735 +f 314/328/736 320/326/737 324/327/738 +f 322/329/739 324/327/740 325/330/741 +f 327/331/742 326/332/743 328/333/744 +f 219/220/745 216/219/746 327/331/747 +f 85/271/748 219/220/749 328/333/750 +f 267/267/751 328/333/752 329/334/753 +f 222/221/754 6/8/755 330/264/756 +f 216/219/757 222/221/758 331/266/759 +f 327/331/760 331/266/761 332/335/762 +f 427/336/763 397/337/764 396/338/765 +f 337/339/766 336/340/767 334/341/768 +f 265/268/769 336/340/770 337/339/771 +f 337/339/772 353/342/773 355/343/774 +f 339/344/775 340/345/776 342/346/777 +f 340/345/778 348/347/779 350/348/780 +f 342/346/781 343/349/782 345/350/783 +f 346/351/784 345/350/785 343/349/786 +f 325/330/787 321/319/788 345/350/789 +f 263/352/790 325/330/791 346/351/792 +f 344/353/793 346/351/794 347/354/795 +f 351/355/796 350/348/797 348/347/798 +f 347/354/799 343/349/800 350/348/801 +f 341/356/802 347/354/803 351/355/804 +f 349/357/805 351/355/806 352/358/807 +f 353/342/808 361/359/809 363/360/810 +f 355/343/811 356/361/812 358/362/813 +f 359/363/814 358/362/815 356/361/816 +f 352/358/817 348/347/818 358/362/819 +f 338/364/820 352/358/821 359/363/822 +f 357/365/823 359/363/824 360/366/825 +f 364/367/826 363/360/827 361/359/828 +f 360/366/829 356/361/830 363/360/831 +f 354/368/832 360/366/833 364/367/834 +f 362/369/835 364/367/836 365/370/837 +f 366/371/838 382/372/839 384/373/840 +f 368/374/841 369/375/842 371/376/843 +f 369/375/844 377/377/845 379/378/846 +f 371/376/847 372/379/848 374/380/849 +f 375/381/850 374/380/851 372/379/852 +f 365/370/853 361/359/854 374/380/855 +f 335/382/856 365/370/857 375/381/858 +f 373/383/859 375/381/860 376/384/861 +f 380/385/862 379/378/863 377/377/864 +f 376/384/865 372/379/866 379/378/867 +f 370/386/868 376/384/869 380/385/870 +f 378/387/871 380/385/872 381/388/873 +f 382/372/874 390/389/875 392/390/876 +f 384/373/877 385/391/878 387/392/879 +f 388/393/880 387/392/881 385/391/882 +f 381/388/883 377/377/884 387/392/885 +f 367/394/886 381/388/887 388/393/888 +f 386/395/889 388/393/890 389/396/891 +f 393/397/892 392/390/893 390/389/894 +f 389/396/895 385/391/896 392/390/897 +f 383/398/898 389/396/899 393/397/900 +f 391/399/901 393/397/902 394/400/903 +f 366/371/904 334/341/905 396/338/906 +f 397/337/907 413/401/908 415/402/909 +f 399/403/910 400/404/911 402/405/912 +f 400/404/913 408/406/914 410/407/915 +f 402/405/916 403/408/917 405/409/918 +f 406/410/919 405/409/920 403/408/921 +f 394/400/922 390/389/923 405/409/924 +f 333/411/925 394/400/926 406/410/927 +f 404/412/928 406/410/929 407/413/930 +f 411/414/931 410/407/932 408/406/933 +f 407/413/934 403/408/935 410/407/936 +f 401/415/937 407/413/938 411/414/939 +f 409/416/940 411/414/941 412/417/942 +f 413/401/943 421/418/944 423/419/945 +f 415/402/946 416/420/947 418/421/948 +f 419/422/949 418/421/950 416/420/951 +f 412/417/952 408/406/953 418/421/954 +f 398/423/955 412/417/956 419/422/957 +f 417/424/958 419/422/959 420/425/960 +f 424/426/961 423/419/962 421/418/963 +f 420/425/964 416/420/965 423/419/966 +f 414/427/967 420/425/968 424/426/969 +f 422/428/970 424/426/971 425/429/972 +f 428/430/973 427/336/974 13/431/975 +f 427/336/976 428/430/977 430/432/978 +f 428/430/979 436/433/980 438/434/981 +f 430/432/982 431/435/983 433/436/984 +f 434/437/985 433/436/986 431/435/987 +f 425/429/988 421/418/989 433/436/990 +f 395/438/991 425/429/992 434/437/993 +f 432/439/994 434/437/995 435/440/996 +f 439/441/997 438/434/998 436/433/999 +f 435/440/1000 431/435/1001 438/434/1002 +f 429/442/1003 435/440/1004 439/441/1005 +f 437/443/1006 439/441/1007 440/444/1008 +f 1/445/1009 426/446/1010 440/444/1011 +f 446/447/1012 441/448/1013 447/449/1014 +f 444/450/1015 443/451/1016 442/452/1017 +f 329/334/1018 326/332/1019 443/451/1020 +f 265/268/1021 329/334/1022 444/450/1023 +f 336/340/1024 444/450/1025 445/453/1026 +f 332/335/1027 264/265/1028 446/447/1029 +f 326/332/1030 332/335/1031 447/449/1032 +f 443/451/1033 447/449/1034 448/454/1035 +f 450/455/1036 449/456/1037 75/457/1038 +f 445/453/1039 442/452/1040 449/456/1041 +f 334/341/1042 445/453/1043 450/455/1044 +f 396/338/1045 450/455/1046 78/458/1047 +f 448/454/1048 441/448/1049 451/262/1050 +f 442/452/1051 448/454/1052 452/261/1053 +f 449/456/1054 452/261/1055 82/459/1056 +f 462/460/1057 453/461/1058 463/462/1059 +f 456/463/1060 455/464/1061 454/465/1062 +f 247/247/1063 240/242/1064 455/464/1065 +f 6/8/1066 247/247/1067 456/463/1068 +f 330/264/1069 456/463/1070 457/466/1071 +f 460/467/1072 459/468/1073 458/469/1074 +f 259/259/1075 256/258/1076 459/468/1077 +f 240/242/1078 259/259/1079 460/467/1080 +f 455/464/1081 460/467/1082 461/470/1083 +f 3/5/1084 462/460/1085 262/260/1086 +f 256/258/1087 262/260/1088 463/462/1089 +f 459/468/1090 463/462/1091 464/471/1092 +f 470/472/1093 469/473/1094 224/474/1095 +f 467/475/1096 466/476/1097 465/477/1098 +f 457/466/1099 454/465/1100 466/476/1101 +f 264/265/1102 457/466/1103 467/475/1104 +f 446/447/1105 467/475/1106 468/478/1107 +f 468/478/1108 465/477/1109 469/473/1110 +f 441/448/1111 468/478/1112 470/472/1113 +f 451/262/1114 470/472/1115 227/479/1116 +f 476/480/1117 471/481/1118 477/482/1119 +f 474/483/1120 473/484/1121 472/485/1122 +f 461/470/1123 458/469/1124 473/484/1125 +f 454/465/1126 461/470/1127 474/483/1128 +f 466/476/1129 474/483/1130 475/486/1131 +f 453/461/1132 476/480/1133 464/471/1134 +f 458/469/1135 464/471/1136 477/482/1137 +f 473/484/1138 477/482/1139 478/487/1140 +f 480/488/1141 479/489/1142 230/490/1143 +f 475/486/1144 472/485/1145 479/489/1146 +f 465/477/1147 475/486/1148 480/488/1149 +f 469/473/1150 480/488/1151 233/491/1152 +f 471/481/1153 481/1/1154 478/487/1155 +f 472/485/1156 478/487/1157 482/3/1158 +f 479/489/1159 482/3/1160 237/492/1161 +f 2/2/1162 237/492/1163 482/3/1164 +f 3/5/1165 262/260/1166 261/6/1167 +f 6/8/1168 222/221/1169 221/9/1170 +f 7/11/1171 84/87/1172 83/12/1173 +f 48/52/1174 14/18/1175 11/13/1176 +f 11/13/1177 46/15/1178 48/52/1179 +f 11/13/1180 14/18/1181 15/21/1182 +f 15/21/1183 13/16/1184 11/13/1185 +f 35/20/1186 18/22/1187 15/21/1188 +f 15/21/1189 14/18/1190 35/20/1191 +f 19/23/1192 17/493/1193 13/16/1194 +f 13/16/1195 15/21/1196 19/23/1197 +f 30/25/1198 22/26/1199 19/23/1200 +f 30/25/1201 19/23/1202 18/22/1203 +f 23/27/1204 21/30/1205 17/493/1206 +f 17/493/1207 19/23/1208 23/27/1209 +f 22/26/1210 27/33/1211 26/28/1212 +f 23/27/1213 26/28/1214 25/29/1215 +f 26/28/1216 24/32/1217 1/31/1218 +f 27/33/1219 20/35/1220 24/32/1221 +f 28/24/1222 32/37/1223 31/34/1224 +f 30/25/1225 31/34/1226 27/33/1227 +f 31/34/1228 29/36/1229 20/35/1230 +f 32/37/1231 16/43/1232 29/36/1233 +f 43/39/1234 36/40/1235 35/20/1236 +f 35/20/1237 33/19/1238 43/39/1239 +f 38/41/1240 28/24/1241 18/22/1242 +f 18/22/1243 35/20/1244 38/41/1245 +f 36/40/1246 40/45/1247 39/42/1248 +f 38/41/1249 39/42/1250 32/37/1251 +f 39/42/1252 37/44/1253 16/43/1254 +f 40/45/1255 34/47/1256 37/44/1257 +f 41/38/1258 45/49/1259 44/46/1260 +f 43/39/1261 44/46/1262 40/45/1263 +f 44/46/1264 42/48/1265 34/47/1266 +f 45/49/1267 12/59/1268 42/48/1269 +f 46/15/1270 62/66/1271 64/50/1272 +f 64/50/1273 48/52/1274 46/15/1275 +f 51/53/1276 33/19/1277 14/18/1278 +f 14/18/1279 48/52/1280 51/53/1281 +f 59/55/1282 52/56/1283 51/53/1284 +f 51/53/1285 49/51/1286 59/55/1287 +f 54/57/1288 41/38/1289 33/19/1290 +f 54/57/1291 33/19/1292 51/53/1293 +f 52/56/1294 56/61/1295 55/58/1296 +f 54/57/1297 55/58/1298 45/49/1299 +f 55/58/1300 53/60/1301 12/59/1302 +f 56/61/1303 50/63/1304 53/60/1305 +f 57/54/1306 61/65/1307 60/62/1308 +f 59/55/1309 60/62/1310 56/61/1311 +f 60/62/1312 58/64/1313 50/63/1314 +f 61/65/1315 47/72/1316 58/64/1317 +f 72/68/1318 65/69/1319 64/50/1320 +f 64/50/1321 62/66/1322 72/68/1323 +f 67/70/1324 57/54/1325 49/51/1326 +f 67/70/1327 49/51/1328 64/50/1329 +f 65/69/1330 69/74/1331 68/71/1332 +f 67/70/1333 68/71/1334 61/65/1335 +f 68/71/1336 66/73/1337 47/72/1338 +f 69/74/1339 63/76/1340 66/73/1341 +f 70/67/1342 74/78/1343 73/75/1344 +f 72/68/1345 73/75/1346 69/74/1347 +f 73/75/1348 71/77/1349 63/76/1350 +f 74/78/1351 8/104/1352 71/77/1353 +f 76/80/1354 80/84/1355 79/81/1356 +f 77/79/1357 79/81/1358 78/82/1359 +f 79/81/1360 11/13/1361 9/17/1362 +f 80/84/1363 10/14/1364 11/13/1365 +f 81/10/1366 83/12/1367 82/85/1368 +f 83/12/1369 77/79/1370 75/83/1371 +f 84/87/1372 76/80/1373 77/79/1374 +f 149/90/1375 85/271/1376 179/270/1377 +f 149/90/1378 179/270/1379 181/88/1380 +f 87/93/1381 119/123/1382 121/126/1383 +f 121/126/1384 90/91/1385 87/93/1386 +f 92/96/1387 46/15/1388 10/14/1389 +f 10/14/1390 90/91/1391 92/96/1392 +f 108/95/1393 93/97/1394 92/96/1395 +f 108/95/1396 92/96/1397 90/91/1398 +f 95/98/1399 62/66/1400 46/15/1401 +f 95/98/1402 46/15/1403 92/96/1404 +f 103/100/1405 96/101/1406 95/98/1407 +f 103/100/1408 95/98/1409 93/97/1410 +f 98/102/1411 70/67/1412 62/66/1413 +f 98/102/1414 62/66/1415 95/98/1416 +f 96/101/1417 100/106/1418 99/103/1419 +f 98/102/1420 99/103/1421 74/78/1422 +f 99/103/1423 97/105/1424 8/104/1425 +f 100/106/1426 94/108/1427 97/105/1428 +f 101/99/1429 105/110/1430 104/107/1431 +f 103/100/1432 104/107/1433 100/106/1434 +f 104/107/1435 102/109/1436 94/108/1437 +f 105/110/1438 91/116/1439 102/109/1440 +f 116/112/1441 109/113/1442 108/95/1443 +f 116/112/1444 108/95/1445 106/94/1446 +f 111/114/1447 101/99/1448 93/97/1449 +f 93/97/1450 108/95/1451 111/114/1452 +f 109/113/1453 113/118/1454 112/115/1455 +f 111/114/1456 112/115/1457 105/110/1458 +f 112/115/1459 110/117/1460 91/116/1461 +f 113/118/1462 107/120/1463 110/117/1464 +f 114/111/1465 118/122/1466 117/119/1467 +f 116/112/1468 117/119/1469 113/118/1470 +f 117/119/1471 115/121/1472 107/120/1473 +f 118/122/1474 88/134/1475 115/121/1476 +f 137/125/1477 122/127/1478 121/126/1479 +f 121/126/1480 119/123/1481 137/125/1482 +f 124/128/1483 106/94/1484 90/91/1485 +f 90/91/1486 121/126/1487 124/128/1488 +f 132/130/1489 125/131/1490 124/128/1491 +f 132/130/1492 124/128/1493 122/127/1494 +f 127/132/1495 114/111/1496 106/94/1497 +f 106/94/1498 124/128/1499 127/132/1500 +f 125/131/1501 129/136/1502 128/133/1503 +f 127/132/1504 128/133/1505 118/122/1506 +f 128/133/1507 126/135/1508 88/134/1509 +f 129/136/1510 123/138/1511 126/135/1512 +f 130/129/1513 134/140/1514 133/137/1515 +f 132/130/1516 133/137/1517 129/136/1518 +f 133/137/1519 131/139/1520 123/138/1521 +f 134/140/1522 120/146/1523 131/139/1524 +f 145/142/1525 138/143/1526 137/125/1527 +f 137/125/1528 135/124/1529 145/142/1530 +f 140/144/1531 130/129/1532 122/127/1533 +f 122/127/1534 137/125/1535 140/144/1536 +f 138/143/1537 142/148/1538 141/145/1539 +f 140/144/1540 141/145/1541 134/140/1542 +f 141/145/1543 139/147/1544 120/146/1545 +f 142/148/1546 136/150/1547 139/147/1548 +f 143/141/1549 147/152/1550 146/149/1551 +f 145/142/1552 146/149/1553 142/148/1554 +f 146/149/1555 144/151/1556 136/150/1557 +f 147/152/1558 86/163/1559 144/151/1560 +f 149/90/1561 150/89/1562 152/155/1563 +f 152/155/1564 119/123/1565 149/90/1566 +f 168/154/1567 153/156/1568 152/155/1569 +f 168/154/1570 152/155/1571 150/89/1572 +f 155/157/1573 135/124/1574 119/123/1575 +f 119/123/1576 152/155/1577 155/157/1578 +f 163/159/1579 156/160/1580 155/157/1581 +f 155/157/1582 153/156/1583 163/159/1584 +f 158/161/1585 143/141/1586 135/124/1587 +f 158/161/1588 135/124/1589 155/157/1590 +f 156/160/1591 160/165/1592 159/162/1593 +f 158/161/1594 159/162/1595 147/152/1596 +f 159/162/1597 157/164/1598 86/163/1599 +f 160/165/1600 154/167/1601 157/164/1602 +f 161/158/1603 165/169/1604 164/166/1605 +f 163/159/1606 164/166/1607 160/165/1608 +f 164/166/1609 162/168/1610 154/167/1611 +f 165/169/1612 151/175/1613 162/168/1614 +f 176/171/1615 169/172/1616 168/154/1617 +f 168/154/1618 166/153/1619 176/171/1620 +f 171/173/1621 161/158/1622 153/156/1623 +f 171/173/1624 153/156/1625 168/154/1626 +f 169/172/1627 173/177/1628 172/174/1629 +f 171/173/1630 172/174/1631 165/169/1632 +f 172/174/1633 170/176/1634 151/175/1635 +f 173/177/1636 167/179/1637 170/176/1638 +f 174/170/1639 178/181/1640 177/178/1641 +f 176/171/1642 177/178/1643 173/177/1644 +f 177/178/1645 175/180/1646 167/179/1647 +f 178/181/1648 148/190/1649 175/180/1650 +f 179/270/1651 195/494/1652 197/182/1653 +f 197/182/1654 181/88/1655 179/270/1656 +f 184/184/1657 166/153/1658 150/89/1659 +f 184/184/1660 150/89/1661 181/88/1662 +f 192/186/1663 185/187/1664 184/184/1665 +f 192/186/1666 184/184/1667 182/183/1668 +f 187/188/1669 174/170/1670 166/153/1671 +f 187/188/1672 166/153/1673 184/184/1674 +f 185/187/1675 189/192/1676 188/189/1677 +f 187/188/1678 188/189/1679 178/181/1680 +f 188/189/1681 186/191/1682 148/190/1683 +f 189/192/1684 183/194/1685 186/191/1686 +f 190/185/1687 194/196/1688 193/193/1689 +f 192/186/1690 193/193/1691 189/192/1692 +f 193/193/1693 191/195/1694 183/194/1695 +f 194/196/1696 180/201/1697 191/195/1698 +f 195/494/1699 203/205/1700 205/197/1701 +f 205/197/1702 197/182/1703 195/494/1704 +f 200/199/1705 190/185/1706 182/183/1707 +f 182/183/1708 197/182/1709 200/199/1710 +f 198/198/1711 202/203/1712 201/200/1713 +f 200/199/1714 201/200/1715 194/196/1716 +f 201/200/1717 199/202/1718 180/201/1719 +f 202/203/1720 196/206/1721 199/202/1722 +f 203/205/1723 207/208/1724 206/204/1725 +f 205/197/1726 206/204/1727 202/203/1728 +f 206/204/1729 204/207/1730 196/206/1731 +f 207/208/1732 4/283/1733 204/207/1734 +f 208/210/1735 215/216/1736 214/211/1737 +f 209/214/1738 212/215/1739 211/212/1740 +f 210/213/1741 211/212/1742 80/84/1743 +f 211/212/1744 89/92/1745 10/14/1746 +f 212/215/1747 87/93/1748 89/92/1749 +f 213/209/1750 214/211/1751 84/87/1752 +f 214/211/1753 210/213/1754 76/80/1755 +f 215/216/1756 209/214/1757 210/213/1758 +f 216/219/1759 219/220/1760 218/217/1761 +f 217/218/1762 218/217/1763 212/215/1764 +f 218/217/1765 149/90/1766 87/93/1767 +f 219/220/1768 85/271/1769 149/90/1770 +f 220/7/1771 221/9/1772 215/216/1773 +f 221/9/1774 217/218/1775 209/214/1776 +f 222/221/1777 216/219/1778 217/218/1779 +f 223/223/1780 239/239/1781 238/224/1782 +f 225/226/1783 229/230/1784 228/227/1785 +f 226/225/1786 228/227/1787 227/228/1788 +f 228/227/1789 81/10/1790 5/86/1791 +f 229/230/1792 7/11/1793 81/10/1794 +f 231/232/1795 235/236/1796 234/233/1797 +f 232/231/1798 234/233/1799 233/234/1800 +f 234/233/1801 226/225/1802 224/229/1803 +f 235/236/1804 225/226/1805 226/225/1806 +f 236/222/1807 238/224/1808 237/237/1809 +f 238/224/1810 232/231/1811 230/235/1812 +f 239/239/1813 231/232/1814 232/231/1815 +f 240/242/1816 247/247/1817 246/240/1818 +f 241/245/1819 244/246/1820 243/243/1821 +f 242/244/1822 243/243/1823 229/230/1824 +f 243/243/1825 213/209/1826 7/11/1827 +f 244/246/1828 208/210/1829 213/209/1830 +f 245/241/1831 246/240/1832 244/246/1833 +f 246/240/1834 220/7/1835 208/210/1836 +f 247/247/1837 6/8/1838 220/7/1839 +f 248/249/1840 255/255/1841 254/250/1842 +f 249/253/1843 252/254/1844 251/251/1845 +f 250/252/1846 251/251/1847 235/236/1848 +f 251/251/1849 242/244/1850 225/226/1851 +f 252/254/1852 241/245/1853 242/244/1854 +f 253/248/1855 254/250/1856 239/239/1857 +f 254/250/1858 250/252/1859 231/232/1860 +f 255/255/1861 249/253/1862 250/252/1863 +f 256/258/1864 259/259/1865 258/256/1866 +f 257/257/1867 258/256/1868 252/254/1869 +f 258/256/1870 245/241/1871 241/245/1872 +f 259/259/1873 240/242/1874 245/241/1875 +f 260/4/1876 261/6/1877 255/255/1878 +f 261/6/1879 257/257/1880 249/253/1881 +f 262/260/1882 256/258/1883 257/257/1884 +f 5/263/1885 82/459/1886 452/261/1887 +f 264/265/1888 332/335/1889 331/266/1890 +f 299/304/1891 268/272/1892 267/267/1893 +f 267/267/1894 297/269/1895 299/304/1896 +f 267/267/1897 268/272/1898 270/275/1899 +f 270/275/1900 179/270/1901 267/267/1902 +f 286/274/1903 271/276/1904 270/275/1905 +f 270/275/1906 268/272/1907 286/274/1908 +f 273/277/1909 195/494/1910 179/270/1911 +f 179/270/1912 270/275/1913 273/277/1914 +f 281/279/1915 274/280/1916 273/277/1917 +f 281/279/1918 273/277/1919 271/276/1920 +f 276/281/1921 203/205/1922 195/494/1923 +f 195/494/1924 273/277/1925 276/281/1926 +f 274/280/1927 278/285/1928 277/282/1929 +f 276/281/1930 277/282/1931 207/208/1932 +f 277/282/1933 275/284/1934 4/283/1935 +f 278/285/1936 272/287/1937 275/284/1938 +f 279/278/1939 283/289/1940 282/286/1941 +f 281/279/1942 282/286/1943 278/285/1944 +f 282/286/1945 280/288/1946 272/287/1947 +f 283/289/1948 269/295/1949 280/288/1950 +f 294/291/1951 287/292/1952 286/274/1953 +f 286/274/1954 284/273/1955 294/291/1956 +f 289/293/1957 279/278/1958 271/276/1959 +f 271/276/1960 286/274/1961 289/293/1962 +f 287/292/1963 291/297/1964 290/294/1965 +f 289/293/1966 290/294/1967 283/289/1968 +f 290/294/1969 288/296/1970 269/295/1971 +f 291/297/1972 285/299/1973 288/296/1974 +f 292/290/1975 296/301/1976 295/298/1977 +f 294/291/1978 295/298/1979 291/297/1980 +f 295/298/1981 293/300/1982 285/299/1983 +f 296/301/1984 266/312/1985 293/300/1986 +f 315/303/1987 300/305/1988 299/304/1989 +f 315/303/1990 299/304/1991 297/269/1992 +f 302/306/1993 284/273/1994 268/272/1995 +f 268/272/1996 299/304/1997 302/306/1998 +f 310/308/1999 303/309/2000 302/306/2001 +f 302/306/2002 300/305/2003 310/308/2004 +f 305/310/2005 292/290/2006 284/273/2007 +f 305/310/2008 284/273/2009 302/306/2010 +f 303/309/2011 307/314/2012 306/311/2013 +f 305/310/2014 306/311/2015 296/301/2016 +f 306/311/2017 304/313/2018 266/312/2019 +f 307/314/2020 301/316/2021 304/313/2022 +f 308/307/2023 312/318/2024 311/315/2025 +f 310/308/2026 311/315/2027 307/314/2028 +f 311/315/2029 309/317/2030 301/316/2031 +f 312/318/2032 298/324/2033 309/317/2034 +f 323/320/2035 316/321/2036 315/303/2037 +f 315/303/2038 313/302/2039 323/320/2040 +f 318/322/2041 308/307/2042 300/305/2043 +f 318/322/2044 300/305/2045 315/303/2046 +f 316/321/2047 320/326/2048 319/323/2049 +f 318/322/2050 319/323/2051 312/318/2052 +f 319/323/2053 317/325/2054 298/324/2055 +f 320/326/2056 314/328/2057 317/325/2058 +f 321/319/2059 325/330/2060 324/327/2061 +f 323/320/2062 324/327/2063 320/326/2064 +f 324/327/2065 322/329/2066 314/328/2067 +f 325/330/2068 263/352/2069 322/329/2070 +f 326/332/2071 329/334/2072 328/333/2073 +f 327/331/2074 328/333/2075 219/220/2076 +f 328/333/2077 267/267/2078 85/271/2079 +f 329/334/2080 265/268/2081 267/267/2082 +f 330/264/2083 331/266/2084 222/221/2085 +f 331/266/2086 327/331/2087 216/219/2088 +f 332/335/2089 326/332/2090 327/331/2091 +f 396/338/2092 9/495/2093 13/431/2094 +f 396/338/2095 13/431/2096 427/336/2097 +f 334/341/2098 366/371/2099 368/374/2100 +f 368/374/2101 337/339/2102 334/341/2103 +f 339/344/2104 297/269/2105 265/268/2106 +f 265/268/2107 337/339/2108 339/344/2109 +f 355/343/2110 340/345/2111 339/344/2112 +f 355/343/2113 339/344/2114 337/339/2115 +f 342/346/2116 313/302/2117 297/269/2118 +f 342/346/2119 297/269/2120 339/344/2121 +f 350/348/2122 343/349/2123 342/346/2124 +f 350/348/2125 342/346/2126 340/345/2127 +f 345/350/2128 321/319/2129 313/302/2130 +f 345/350/2131 313/302/2132 342/346/2133 +f 343/349/2134 347/354/2135 346/351/2136 +f 345/350/2137 346/351/2138 325/330/2139 +f 346/351/2140 344/353/2141 263/352/2142 +f 347/354/2143 341/356/2144 344/353/2145 +f 348/347/2146 352/358/2147 351/355/2148 +f 350/348/2149 351/355/2150 347/354/2151 +f 351/355/2152 349/357/2153 341/356/2154 +f 352/358/2155 338/364/2156 349/357/2157 +f 363/360/2158 356/361/2159 355/343/2160 +f 363/360/2161 355/343/2162 353/342/2163 +f 358/362/2164 348/347/2165 340/345/2166 +f 340/345/2167 355/343/2168 358/362/2169 +f 356/361/2170 360/366/2171 359/363/2172 +f 358/362/2173 359/363/2174 352/358/2175 +f 359/363/2176 357/365/2177 338/364/2178 +f 360/366/2179 354/368/2180 357/365/2181 +f 361/359/2182 365/370/2183 364/367/2184 +f 363/360/2185 364/367/2186 360/366/2187 +f 364/367/2188 362/369/2189 354/368/2190 +f 365/370/2191 335/382/2192 362/369/2193 +f 384/373/2194 369/375/2195 368/374/2196 +f 368/374/2197 366/371/2198 384/373/2199 +f 371/376/2200 353/342/2201 337/339/2202 +f 337/339/2203 368/374/2204 371/376/2205 +f 379/378/2206 372/379/2207 371/376/2208 +f 379/378/2209 371/376/2210 369/375/2211 +f 374/380/2212 361/359/2213 353/342/2214 +f 353/342/2215 371/376/2216 374/380/2217 +f 372/379/2218 376/384/2219 375/381/2220 +f 374/380/2221 375/381/2222 365/370/2223 +f 375/381/2224 373/383/2225 335/382/2226 +f 376/384/2227 370/386/2228 373/383/2229 +f 377/377/2230 381/388/2231 380/385/2232 +f 379/378/2233 380/385/2234 376/384/2235 +f 380/385/2236 378/387/2237 370/386/2238 +f 381/388/2239 367/394/2240 378/387/2241 +f 392/390/2242 385/391/2243 384/373/2244 +f 384/373/2245 382/372/2246 392/390/2247 +f 387/392/2248 377/377/2249 369/375/2250 +f 369/375/2251 384/373/2252 387/392/2253 +f 385/391/2254 389/396/2255 388/393/2256 +f 387/392/2257 388/393/2258 381/388/2259 +f 388/393/2260 386/395/2261 367/394/2262 +f 389/396/2263 383/398/2264 386/395/2265 +f 390/389/2266 394/400/2267 393/397/2268 +f 392/390/2269 393/397/2270 389/396/2271 +f 393/397/2272 391/399/2273 383/398/2274 +f 394/400/2275 333/411/2276 391/399/2277 +f 396/338/2278 397/337/2279 399/403/2280 +f 399/403/2281 366/371/2282 396/338/2283 +f 415/402/2284 400/404/2285 399/403/2286 +f 415/402/2287 399/403/2288 397/337/2289 +f 402/405/2290 382/372/2291 366/371/2292 +f 366/371/2293 399/403/2294 402/405/2295 +f 410/407/2296 403/408/2297 402/405/2298 +f 402/405/2299 400/404/2300 410/407/2301 +f 405/409/2302 390/389/2303 382/372/2304 +f 405/409/2305 382/372/2306 402/405/2307 +f 403/408/2308 407/413/2309 406/410/2310 +f 405/409/2311 406/410/2312 394/400/2313 +f 406/410/2314 404/412/2315 333/411/2316 +f 407/413/2317 401/415/2318 404/412/2319 +f 408/406/2320 412/417/2321 411/414/2322 +f 410/407/2323 411/414/2324 407/413/2325 +f 411/414/2326 409/416/2327 401/415/2328 +f 412/417/2329 398/423/2330 409/416/2331 +f 423/419/2332 416/420/2333 415/402/2334 +f 415/402/2335 413/401/2336 423/419/2337 +f 418/421/2338 408/406/2339 400/404/2340 +f 418/421/2341 400/404/2342 415/402/2343 +f 416/420/2344 420/425/2345 419/422/2346 +f 418/421/2347 419/422/2348 412/417/2349 +f 419/422/2350 417/424/2351 398/423/2352 +f 420/425/2353 414/427/2354 417/424/2355 +f 421/418/2356 425/429/2357 424/426/2358 +f 423/419/2359 424/426/2360 420/425/2361 +f 424/426/2362 422/428/2363 414/427/2364 +f 425/429/2365 395/438/2366 422/428/2367 +f 13/431/2368 17/496/2369 428/430/2370 +f 430/432/2371 413/401/2372 397/337/2373 +f 430/432/2374 397/337/2375 427/336/2376 +f 438/434/2377 431/435/2378 430/432/2379 +f 438/434/2380 430/432/2381 428/430/2382 +f 433/436/2383 421/418/2384 413/401/2385 +f 433/436/2386 413/401/2387 430/432/2388 +f 431/435/2389 435/440/2390 434/437/2391 +f 433/436/2392 434/437/2393 425/429/2394 +f 434/437/2395 432/439/2396 395/438/2397 +f 435/440/2398 429/442/2399 432/439/2400 +f 436/433/2401 440/444/2402 439/441/2403 +f 438/434/2404 439/441/2405 435/440/2406 +f 439/441/2407 437/443/2408 429/442/2409 +f 440/444/2410 426/446/2411 437/443/2412 +f 428/430/2413 17/496/2414 21/497/2415 +f 436/433/2416 428/430/2417 1/445/2418 +f 440/444/2419 436/433/2420 1/445/2421 +f 25/498/2422 1/445/2423 428/430/2424 +f 428/430/2425 21/497/2426 25/498/2427 +f 441/448/2428 448/454/2429 447/449/2430 +f 442/452/2431 445/453/2432 444/450/2433 +f 443/451/2434 444/450/2435 329/334/2436 +f 444/450/2437 336/340/2438 265/268/2439 +f 445/453/2440 334/341/2441 336/340/2442 +f 446/447/2443 447/449/2444 332/335/2445 +f 447/449/2446 443/451/2447 326/332/2448 +f 448/454/2449 442/452/2450 443/451/2451 +f 75/457/2452 78/458/2453 450/455/2454 +f 449/456/2455 450/455/2456 445/453/2457 +f 450/455/2458 396/338/2459 334/341/2460 +f 78/458/2461 9/495/2462 396/338/2463 +f 451/262/2464 452/261/2465 448/454/2466 +f 452/261/2467 449/456/2468 442/452/2469 +f 82/459/2470 75/457/2471 449/456/2472 +f 453/461/2473 464/471/2474 463/462/2475 +f 454/465/2476 457/466/2477 456/463/2478 +f 455/464/2479 456/463/2480 247/247/2481 +f 456/463/2482 330/264/2483 6/8/2484 +f 457/466/2485 264/265/2486 330/264/2487 +f 458/469/2488 461/470/2489 460/467/2490 +f 459/468/2491 460/467/2492 259/259/2493 +f 460/467/2494 455/464/2495 240/242/2496 +f 461/470/2497 454/465/2498 455/464/2499 +f 462/460/2500 463/462/2501 262/260/2502 +f 463/462/2503 459/468/2504 256/258/2505 +f 464/471/2506 458/469/2507 459/468/2508 +f 224/474/2509 227/479/2510 470/472/2511 +f 465/477/2512 468/478/2513 467/475/2514 +f 466/476/2515 467/475/2516 457/466/2517 +f 467/475/2518 446/447/2519 264/265/2520 +f 468/478/2521 441/448/2522 446/447/2523 +f 469/473/2524 470/472/2525 468/478/2526 +f 470/472/2527 451/262/2528 441/448/2529 +f 227/479/2530 5/263/2531 451/262/2532 +f 471/481/2533 478/487/2534 477/482/2535 +f 472/485/2536 475/486/2537 474/483/2538 +f 473/484/2539 474/483/2540 461/470/2541 +f 474/483/2542 466/476/2543 454/465/2544 +f 475/486/2545 465/477/2546 466/476/2547 +f 476/480/2548 477/482/2549 464/471/2550 +f 477/482/2551 473/484/2552 458/469/2553 +f 478/487/2554 472/485/2555 473/484/2556 +f 230/490/2557 233/491/2558 480/488/2559 +f 479/489/2560 480/488/2561 475/486/2562 +f 480/488/2563 469/473/2564 465/477/2565 +f 233/491/2566 224/474/2567 469/473/2568 +f 481/1/2569 482/3/2570 478/487/2571 +f 482/3/2572 479/489/2573 472/485/2574 +f 237/492/2575 230/490/2576 479/489/2577 diff --git a/build/assets/glass.mtl b/build/assets/glass.mtl new file mode 100644 index 0000000..c89145d --- /dev/null +++ b/build/assets/glass.mtl @@ -0,0 +1,6 @@ +newmtl initialShadingGroup +illum 4 +Kd 0.50 0.50 0.50 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +Ni 1.00 diff --git a/build/assets/lamp-1bcc16.obj b/build/assets/lamp-1bcc16.obj new file mode 100644 index 0000000..4d0a85c --- /dev/null +++ b/build/assets/lamp-1bcc16.obj @@ -0,0 +1,1211 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib lamp.mtl +g default +v 2.656471 15.855046 5.780191 +v 2.535695 15.855046 5.017639 +v 2.656471 15.855046 4.255087 +v 3.006978 15.855046 3.567179 +v 3.552904 15.855046 3.021253 +v 4.240812 15.855046 2.670746 +v 5.003365 15.855046 2.549970 +v 5.765916 15.855046 2.670746 +v 6.453824 15.855046 3.021253 +v 6.999750 15.855046 3.567179 +v 7.350257 15.855046 4.255087 +v 7.471033 15.855046 5.017639 +v 7.350257 15.855046 5.780191 +v 6.999750 15.855046 6.468100 +v 6.453824 15.855046 7.014026 +v 5.765916 15.855046 7.364532 +v 5.003365 15.855046 7.485309 +v 4.240812 15.855046 7.364532 +v 3.552904 15.855046 7.014026 +v 3.006978 15.855046 6.468100 +v 3.327012 19.818167 5.562319 +v 3.240743 19.818167 5.017639 +v 3.327012 19.818167 4.472960 +v 3.577374 19.818167 3.981596 +v 3.967321 19.818167 3.591650 +v 4.458684 19.818167 3.341287 +v 5.003365 19.818167 3.255018 +v 5.548044 19.818167 3.341287 +v 6.039407 19.818167 3.591650 +v 6.429354 19.818167 3.981596 +v 6.679716 19.818167 4.472960 +v 6.765985 19.818167 5.017639 +v 6.679716 19.818167 5.562319 +v 6.429354 19.818167 6.053682 +v 6.039407 19.818167 6.443629 +v 5.548044 19.818167 6.693992 +v 5.003365 19.818167 6.780261 +v 4.458684 19.818167 6.693992 +v 3.967321 19.818167 6.443629 +v 3.577374 19.818167 6.053682 +v 5.003365 19.818167 5.017639 +v 5.003365 15.855044 5.017639 +v 1.159431 0.014822 6.247877 +v 0.961787 0.014822 5.000000 +v 1.159431 0.014822 3.752123 +v 1.733017 0.014822 2.626398 +v 2.626398 0.014822 1.733017 +v 3.752123 0.014822 1.159431 +v 5.000000 0.014822 0.961787 +v 6.247877 0.014822 1.159431 +v 7.373602 0.014822 1.733017 +v 8.266983 0.014822 2.626398 +v 8.840569 0.014822 3.752123 +v 9.038213 0.014822 5.000000 +v 8.840569 0.014822 6.247877 +v 8.266983 0.014822 7.373602 +v 7.373602 0.014822 8.266983 +v 6.247877 0.014822 8.840569 +v 5.000000 0.014822 9.038213 +v 3.752123 0.014822 8.840569 +v 2.626398 0.014822 8.266983 +v 1.733017 0.014822 7.373602 +v 3.736371 -5.387635 5.410578 +v 3.671342 -5.387635 5.000000 +v 3.736371 -5.387635 4.589422 +v 3.925093 -5.387635 4.219035 +v 4.219035 -5.387635 3.925093 +v 4.589422 -5.387635 3.736371 +v 5.000000 -5.387635 3.671342 +v 5.410578 -5.387635 3.736371 +v 5.780965 -5.387635 3.925093 +v 6.074907 -5.387635 4.219035 +v 6.263629 -5.387635 4.589422 +v 6.328658 -5.387635 5.000000 +v 6.263629 -5.387635 5.410578 +v 6.074907 -5.387635 5.780965 +v 5.780965 -5.387635 6.074907 +v 5.410578 -5.387635 6.263629 +v 5.000000 -5.387635 6.328658 +v 4.589422 -5.387635 6.263629 +v 4.219035 -5.387635 6.074907 +v 3.925093 -5.387635 5.780965 +v 3.780450 -5.669678 5.396256 +v 3.717689 -5.669678 5.000000 +v 3.780450 -5.669678 4.603744 +v 3.962589 -5.669678 4.246277 +v 4.246277 -5.669678 3.962589 +v 4.603744 -5.669678 3.780450 +v 5.000000 -5.669678 3.717689 +v 5.396256 -5.669678 3.780450 +v 5.753723 -5.669678 3.962589 +v 6.037411 -5.669678 4.246277 +v 6.219550 -5.669678 4.603744 +v 6.282311 -5.669678 5.000000 +v 6.219550 -5.669678 5.396256 +v 6.037411 -5.669678 5.753723 +v 5.753723 -5.669678 6.037411 +v 5.396256 -5.669678 6.219550 +v 5.000000 -5.669678 6.282311 +v 4.603744 -5.669678 6.219550 +v 4.246277 -5.669678 6.037411 +v 3.962589 -5.669678 5.753723 +v 1.125356 -11.094143 6.258948 +v 0.925958 -11.094143 5.000000 +v 1.125356 -11.094143 3.741052 +v 1.704031 -11.094143 2.605338 +v 2.605338 -11.094143 1.704031 +v 3.741052 -11.094143 1.125356 +v 5.000000 -11.094143 0.925958 +v 6.258948 -11.094143 1.125356 +v 7.394662 -11.094143 1.704031 +v 8.295969 -11.094143 2.605338 +v 8.874644 -11.094143 3.741052 +v 9.074041 -11.094143 5.000000 +v 8.874644 -11.094143 6.258948 +v 8.295969 -11.094143 7.394662 +v 7.394662 -11.094143 8.295969 +v 6.258948 -11.094143 8.874644 +v 5.000000 -11.094143 9.074041 +v 3.741052 -11.094143 8.874644 +v 2.605338 -11.094143 8.295969 +v 1.704031 -11.094143 7.394662 +v 5.000000 0.014822 5.000000 +v 5.000000 -11.094146 5.000000 +vt 0.000000 -1.000000 +vt 1.000000 -1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 2.000000 +vt 0.000000 2.000000 +vt 1.000000 3.000000 +vt 0.000000 3.000000 +vt 1.000000 4.000000 +vt 0.000000 4.000000 +vt 1.000000 5.000000 +vt 0.000000 5.000000 +vt 1.000000 6.000000 +vt 0.000000 6.000000 +vt 1.000000 7.000000 +vt 0.000000 7.000000 +vt 1.000000 8.000000 +vt 0.000000 8.000000 +vt 1.000000 9.000000 +vt 0.000000 9.000000 +vt 1.000000 10.000000 +vt 0.000000 10.000000 +vt 1.000000 11.000000 +vt 0.000000 11.000000 +vt 1.000000 12.000000 +vt 0.000000 12.000000 +vt 1.000000 13.000000 +vt 0.000000 13.000000 +vt 1.000000 14.000000 +vt 0.000000 14.000000 +vt 1.000000 15.000000 +vt 0.000000 15.000000 +vt 1.000000 16.000000 +vt 0.000000 16.000000 +vt 1.000000 17.000000 +vt 0.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 -1.000000 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.333333 -1.000000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.000000 2.000000 +vt 0.333333 2.000000 +vt 0.000000 3.000000 +vt 0.333333 3.000000 +vt 0.000000 4.000000 +vt 0.333333 4.000000 +vt 0.000000 5.000000 +vt 0.333333 5.000000 +vt 0.000000 6.000000 +vt 0.333333 6.000000 +vt 0.000000 7.000000 +vt 0.333333 7.000000 +vt 0.000000 8.000000 +vt 0.333333 8.000000 +vt 0.000000 9.000000 +vt 0.333333 9.000000 +vt 0.000000 10.000000 +vt 0.333333 10.000000 +vt 0.000000 11.000000 +vt 0.333333 11.000000 +vt 0.000000 12.000000 +vt 0.333333 12.000000 +vt 0.000000 13.000000 +vt 0.333333 13.000000 +vt 0.000000 14.000000 +vt 0.333333 14.000000 +vt 0.000000 15.000000 +vt 0.333333 15.000000 +vt 0.000000 16.000000 +vt 0.333333 16.000000 +vt 0.000000 17.000000 +vt 0.333333 17.000000 +vt 0.000000 18.000000 +vt 0.333333 18.000000 +vt 0.666667 0.000000 +vt 0.666667 -1.000000 +vt 0.666667 1.000000 +vt 0.666667 2.000000 +vt 0.666667 3.000000 +vt 0.666667 4.000000 +vt 0.666667 5.000000 +vt 0.666667 6.000000 +vt 0.666667 7.000000 +vt 0.666667 8.000000 +vt 0.666667 9.000000 +vt 0.666667 10.000000 +vt 0.666667 11.000000 +vt 0.666667 12.000000 +vt 0.666667 13.000000 +vt 0.666667 14.000000 +vt 0.666667 15.000000 +vt 0.666667 16.000000 +vt 0.666667 17.000000 +vt 0.666667 18.000000 +vt 1.000000 0.000000 +vt 1.000000 -1.000000 +vt 1.000000 1.000000 +vt 1.000000 2.000000 +vt 1.000000 3.000000 +vt 1.000000 4.000000 +vt 1.000000 5.000000 +vt 1.000000 6.000000 +vt 1.000000 7.000000 +vt 1.000000 8.000000 +vt 1.000000 9.000000 +vt 1.000000 10.000000 +vt 1.000000 11.000000 +vt 1.000000 12.000000 +vt 1.000000 13.000000 +vt 1.000000 14.000000 +vt 1.000000 15.000000 +vt 1.000000 16.000000 +vt 1.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.984541 0.175152 0.000000 +vn -0.984541 0.175152 0.000000 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.936355 0.175152 0.304240 +vn -0.936355 0.175152 0.304240 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.850126 -0.448316 0.276223 +vn -0.893876 -0.448315 0.000000 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 0.277092 +vn -0.893876 -0.448315 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.852801 -0.442663 -0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.723160 -0.448316 -0.525407 +vn -0.725436 -0.442663 -0.527060 +vn -0.852801 -0.442663 -0.277092 +vn -0.723160 -0.448316 -0.525407 +vn -0.525407 -0.448316 -0.723160 +vn -0.527060 -0.442663 -0.725436 +vn -0.725436 -0.442663 -0.527060 +vn -0.525407 -0.448316 -0.723160 +vn -0.276223 -0.448316 -0.850126 +vn -0.277092 -0.442663 -0.852801 +vn -0.527060 -0.442663 -0.725436 +vn -0.276223 -0.448316 -0.850126 +vn 0.000000 -0.448316 -0.893875 +vn 0.000000 -0.442663 -0.896688 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.448316 -0.893875 +vn 0.276223 -0.448316 -0.850126 +vn 0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.276223 -0.448316 -0.850126 +vn 0.525407 -0.448316 -0.723160 +vn 0.527060 -0.442663 -0.725436 +vn 0.277092 -0.442663 -0.852801 +vn 0.525407 -0.448316 -0.723160 +vn 0.723160 -0.448316 -0.525407 +vn 0.725436 -0.442663 -0.527060 +vn 0.527060 -0.442663 -0.725436 +vn 0.723160 -0.448316 -0.525407 +vn 0.850126 -0.448316 -0.276223 +vn 0.852801 -0.442663 -0.277092 +vn 0.725436 -0.442663 -0.527060 +vn 0.850126 -0.448316 -0.276223 +vn 0.893876 -0.448315 0.000000 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 -0.277092 +vn 0.893876 -0.448315 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.852801 -0.442663 0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.723160 -0.448316 0.525407 +vn 0.725436 -0.442663 0.527060 +vn 0.852801 -0.442663 0.277092 +vn 0.723160 -0.448316 0.525407 +vn 0.525407 -0.448316 0.723160 +vn 0.527060 -0.442663 0.725436 +vn 0.725436 -0.442663 0.527060 +vn 0.525407 -0.448316 0.723160 +vn 0.276223 -0.448316 0.850126 +vn 0.277092 -0.442663 0.852801 +vn 0.527060 -0.442663 0.725436 +vn 0.276223 -0.448316 0.850126 +vn 0.000000 -0.448316 0.893875 +vn 0.000000 -0.442663 0.896688 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.448316 0.893875 +vn -0.276223 -0.448316 0.850126 +vn -0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn -0.276223 -0.448316 0.850126 +vn -0.525407 -0.448316 0.723160 +vn -0.527060 -0.442663 0.725436 +vn -0.277092 -0.442663 0.852801 +vn -0.525407 -0.448316 0.723160 +vn -0.723160 -0.448316 0.525407 +vn -0.725436 -0.442663 0.527060 +vn -0.527060 -0.442663 0.725436 +vn -0.723160 -0.448316 0.525407 +vn -0.850126 -0.448316 0.276223 +vn -0.852801 -0.442663 0.277092 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 0.276577 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.851218 0.446020 -0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.725436 -0.442663 -0.527060 +vn -0.724089 0.446020 -0.526081 +vn -0.851218 0.446020 -0.276577 +vn -0.725436 -0.442663 -0.527060 +vn -0.527060 -0.442663 -0.725436 +vn -0.526081 0.446020 -0.724089 +vn -0.724089 0.446020 -0.526081 +vn -0.527060 -0.442663 -0.725436 +vn -0.277092 -0.442663 -0.852801 +vn -0.276577 0.446020 -0.851218 +vn -0.526081 0.446020 -0.724089 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.000000 0.446020 -0.895023 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 -0.442663 -0.896688 +vn 0.277092 -0.442663 -0.852801 +vn 0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.277092 -0.442663 -0.852801 +vn 0.527060 -0.442663 -0.725436 +vn 0.526081 0.446020 -0.724089 +vn 0.276577 0.446020 -0.851218 +vn 0.527060 -0.442663 -0.725436 +vn 0.725436 -0.442663 -0.527060 +vn 0.724089 0.446020 -0.526081 +vn 0.526081 0.446020 -0.724089 +vn 0.725436 -0.442663 -0.527060 +vn 0.852801 -0.442663 -0.277092 +vn 0.851218 0.446020 -0.276577 +vn 0.724089 0.446020 -0.526081 +vn 0.852801 -0.442663 -0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 -0.276577 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.851218 0.446020 0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.725436 -0.442663 0.527060 +vn 0.724089 0.446020 0.526081 +vn 0.851218 0.446020 0.276577 +vn 0.725436 -0.442663 0.527060 +vn 0.527060 -0.442663 0.725436 +vn 0.526081 0.446020 0.724089 +vn 0.724089 0.446020 0.526081 +vn 0.527060 -0.442663 0.725436 +vn 0.277092 -0.442663 0.852801 +vn 0.276577 0.446020 0.851218 +vn 0.526081 0.446020 0.724089 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn 0.000000 0.446020 0.895023 +vn 0.276577 0.446020 0.851218 +vn 0.000000 -0.442663 0.896688 +vn -0.277092 -0.442663 0.852801 +vn -0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn -0.277092 -0.442663 0.852801 +vn -0.527060 -0.442663 0.725436 +vn -0.526081 0.446020 0.724089 +vn -0.276577 0.446020 0.851218 +vn -0.527060 -0.442663 0.725436 +vn -0.725436 -0.442663 0.527060 +vn -0.724089 0.446020 0.526081 +vn -0.526081 0.446020 0.724089 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.851218 0.446020 0.276577 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.889154 0.457608 0.000000 +vn -0.845636 0.457608 0.274764 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.845636 0.457608 -0.274764 +vn -0.889154 0.457608 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.724089 0.446020 -0.526081 +vn -0.719341 0.457608 -0.522631 +vn -0.845636 0.457608 -0.274764 +vn -0.724089 0.446020 -0.526081 +vn -0.526081 0.446020 -0.724089 +vn -0.522632 0.457608 -0.719341 +vn -0.719341 0.457608 -0.522631 +vn -0.526081 0.446020 -0.724089 +vn -0.276577 0.446020 -0.851218 +vn -0.274764 0.457608 -0.845636 +vn -0.522632 0.457608 -0.719341 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.000000 0.457608 -0.889154 +vn -0.274764 0.457608 -0.845636 +vn 0.000000 0.446020 -0.895023 +vn 0.276577 0.446020 -0.851218 +vn 0.274764 0.457608 -0.845636 +vn 0.000000 0.457608 -0.889154 +vn 0.276577 0.446020 -0.851218 +vn 0.526081 0.446020 -0.724089 +vn 0.522632 0.457608 -0.719341 +vn 0.274764 0.457608 -0.845636 +vn 0.526081 0.446020 -0.724089 +vn 0.724089 0.446020 -0.526081 +vn 0.719341 0.457608 -0.522631 +vn 0.522632 0.457608 -0.719341 +vn 0.724089 0.446020 -0.526081 +vn 0.851218 0.446020 -0.276577 +vn 0.845636 0.457608 -0.274764 +vn 0.719341 0.457608 -0.522631 +vn 0.851218 0.446020 -0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.889154 0.457608 0.000000 +vn 0.845636 0.457608 -0.274764 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.845636 0.457608 0.274764 +vn 0.889154 0.457608 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.724089 0.446020 0.526081 +vn 0.719341 0.457608 0.522631 +vn 0.845636 0.457608 0.274764 +vn 0.724089 0.446020 0.526081 +vn 0.526081 0.446020 0.724089 +vn 0.522632 0.457608 0.719341 +vn 0.719341 0.457608 0.522631 +vn 0.526081 0.446020 0.724089 +vn 0.276577 0.446020 0.851218 +vn 0.274764 0.457608 0.845636 +vn 0.522632 0.457608 0.719341 +vn 0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn 0.000000 0.457608 0.889154 +vn 0.274764 0.457608 0.845636 +vn 0.000000 0.446020 0.895023 +vn -0.276577 0.446020 0.851218 +vn -0.274764 0.457608 0.845636 +vn 0.000000 0.457608 0.889154 +vn -0.276577 0.446020 0.851218 +vn -0.526081 0.446020 0.724089 +vn -0.522632 0.457608 0.719341 +vn -0.274764 0.457608 0.845636 +vn -0.526081 0.446020 0.724089 +vn -0.724089 0.446020 0.526081 +vn -0.719341 0.457608 0.522631 +vn -0.522632 0.457608 0.719341 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.845636 0.457608 0.274764 +vn -0.719341 0.457608 0.522631 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +s off +g polySurface1 +usemtl initialShadingGroup +f 1/1/1 21/2/2 22/3/3 2/4/4 +f 2/4/5 22/3/6 23/5/7 3/6/8 +f 3/6/9 23/5/10 24/7/11 4/8/12 +f 4/8/13 24/7/14 25/9/15 5/10/16 +f 5/10/17 25/9/18 26/11/19 6/12/20 +f 6/12/21 26/11/22 27/13/23 7/14/24 +f 7/14/25 27/13/26 28/15/27 8/16/28 +f 8/16/29 28/15/30 29/17/31 9/18/32 +f 9/18/33 29/17/34 30/19/35 10/20/36 +f 10/20/37 30/19/38 31/21/39 11/22/40 +f 11/22/41 31/21/42 32/23/43 12/24/44 +f 12/24/45 32/23/46 33/25/47 13/26/48 +f 13/26/49 33/25/50 34/27/51 14/28/52 +f 14/28/53 34/27/54 35/29/55 15/30/56 +f 15/30/57 35/29/58 36/31/59 16/32/60 +f 16/32/61 36/31/62 37/33/63 17/34/64 +f 17/34/65 37/33/66 38/35/67 18/36/68 +f 18/36/69 38/35/70 39/37/71 19/38/72 +f 19/38/73 39/37/74 40/39/75 20/40/76 +f 20/40/77 40/39/78 21/2/79 1/1/80 +f 22/41/81 21/42/82 41/43/83 +f 23/44/84 22/45/85 41/46/86 +f 24/47/87 23/48/88 41/49/89 +f 25/50/90 24/51/91 41/52/92 +f 26/53/93 25/54/94 41/55/95 +f 27/56/96 26/57/97 41/58/98 +f 28/59/99 27/60/100 41/61/101 +f 29/62/102 28/63/103 41/64/104 +f 30/65/105 29/66/106 41/67/107 +f 31/68/108 30/69/109 41/70/110 +f 32/71/111 31/72/112 41/73/113 +f 33/74/114 32/75/115 41/76/116 +f 34/77/117 33/78/118 41/79/119 +f 35/80/120 34/81/121 41/82/122 +f 36/83/123 35/84/124 41/85/125 +f 37/86/126 36/87/127 41/88/128 +f 38/89/129 37/90/130 41/91/131 +f 39/92/132 38/93/133 41/94/134 +f 40/95/135 39/96/136 41/97/137 +f 21/98/138 40/99/139 41/100/140 +f 1/101/141 2/102/142 42/103/143 +f 2/104/144 3/105/145 42/106/146 +f 3/107/147 4/108/148 42/109/149 +f 4/110/150 5/111/151 42/112/152 +f 5/113/153 6/114/154 42/115/155 +f 6/116/156 7/117/157 42/118/158 +f 7/119/159 8/120/160 42/121/161 +f 8/122/162 9/123/163 42/124/164 +f 9/125/165 10/126/166 42/127/167 +f 10/128/168 11/129/169 42/130/170 +f 11/131/171 12/132/172 42/133/173 +f 12/134/174 13/135/175 42/136/176 +f 13/137/177 14/138/178 42/139/179 +f 14/140/180 15/141/181 42/142/182 +f 15/143/183 16/144/184 42/145/185 +f 16/146/186 17/147/187 42/148/188 +f 17/149/189 18/150/190 42/151/191 +f 18/152/192 19/153/193 42/154/194 +f 19/155/195 20/156/196 42/157/197 +f 20/158/198 1/159/199 42/160/200 +f 43/161/201 44/162/202 64/163/203 63/164/204 +f 44/162/205 45/165/206 65/166/207 64/163/208 +f 45/165/209 46/167/210 66/168/211 65/166/212 +f 46/167/213 47/169/214 67/170/215 66/168/216 +f 47/169/217 48/171/218 68/172/219 67/170/220 +f 48/171/221 49/173/222 69/174/223 68/172/224 +f 49/173/225 50/175/226 70/176/227 69/174/228 +f 50/175/229 51/177/230 71/178/231 70/176/232 +f 51/177/233 52/179/234 72/180/235 71/178/236 +f 52/179/237 53/181/238 73/182/239 72/180/240 +f 53/181/241 54/183/242 74/184/243 73/182/244 +f 54/183/245 55/185/246 75/186/247 74/184/248 +f 55/185/249 56/187/250 76/188/251 75/186/252 +f 56/187/253 57/189/254 77/190/255 76/188/256 +f 57/189/257 58/191/258 78/192/259 77/190/260 +f 58/191/261 59/193/262 79/194/263 78/192/264 +f 59/193/265 60/195/266 80/196/267 79/194/268 +f 60/195/269 61/197/270 81/198/271 80/196/272 +f 61/197/273 62/199/274 82/200/275 81/198/276 +f 62/199/277 43/161/278 63/164/279 82/200/280 +f 63/164/281 64/163/282 84/201/283 83/202/284 +f 64/163/285 65/166/286 85/203/287 84/201/288 +f 65/166/289 66/168/290 86/204/291 85/203/292 +f 66/168/293 67/170/294 87/205/295 86/204/296 +f 67/170/297 68/172/298 88/206/299 87/205/300 +f 68/172/301 69/174/302 89/207/303 88/206/304 +f 69/174/305 70/176/306 90/208/307 89/207/308 +f 70/176/309 71/178/310 91/209/311 90/208/312 +f 71/178/313 72/180/314 92/210/315 91/209/316 +f 72/180/317 73/182/318 93/211/319 92/210/320 +f 73/182/321 74/184/322 94/212/323 93/211/324 +f 74/184/325 75/186/326 95/213/327 94/212/328 +f 75/186/329 76/188/330 96/214/331 95/213/332 +f 76/188/333 77/190/334 97/215/335 96/214/336 +f 77/190/337 78/192/338 98/216/339 97/215/340 +f 78/192/341 79/194/342 99/217/343 98/216/344 +f 79/194/345 80/196/346 100/218/347 99/217/348 +f 80/196/349 81/198/350 101/219/351 100/218/352 +f 81/198/353 82/200/354 102/220/355 101/219/356 +f 82/200/357 63/164/358 83/202/359 102/220/360 +f 83/202/361 84/201/362 104/221/363 103/222/364 +f 84/201/365 85/203/366 105/223/367 104/221/368 +f 85/203/369 86/204/370 106/224/371 105/223/372 +f 86/204/373 87/205/374 107/225/375 106/224/376 +f 87/205/377 88/206/378 108/226/379 107/225/380 +f 88/206/381 89/207/382 109/227/383 108/226/384 +f 89/207/385 90/208/386 110/228/387 109/227/388 +f 90/208/389 91/209/390 111/229/391 110/228/392 +f 91/209/393 92/210/394 112/230/395 111/229/396 +f 92/210/397 93/211/398 113/231/399 112/230/400 +f 93/211/401 94/212/402 114/232/403 113/231/404 +f 94/212/405 95/213/406 115/233/407 114/232/408 +f 95/213/409 96/214/410 116/234/411 115/233/412 +f 96/214/413 97/215/414 117/235/415 116/234/416 +f 97/215/417 98/216/418 118/236/419 117/235/420 +f 98/216/421 99/217/422 119/237/423 118/236/424 +f 99/217/425 100/218/426 120/238/427 119/237/428 +f 100/218/429 101/219/430 121/239/431 120/238/432 +f 101/219/433 102/220/434 122/240/435 121/239/436 +f 102/220/437 83/202/438 103/222/439 122/240/440 +f 44/241/441 43/242/442 123/243/443 +f 45/244/444 44/245/445 123/246/446 +f 46/247/447 45/248/448 123/249/449 +f 47/250/450 46/251/451 123/252/452 +f 48/253/453 47/254/454 123/255/455 +f 49/256/456 48/257/457 123/258/458 +f 50/259/459 49/260/460 123/261/461 +f 51/262/462 50/263/463 123/264/464 +f 52/265/465 51/266/466 123/267/467 +f 53/268/468 52/269/469 123/270/470 +f 54/271/471 53/272/472 123/273/473 +f 55/274/474 54/275/475 123/276/476 +f 56/277/477 55/278/478 123/279/479 +f 57/280/480 56/281/481 123/282/482 +f 58/283/483 57/284/484 123/285/485 +f 59/286/486 58/287/487 123/288/488 +f 60/289/489 59/290/490 123/291/491 +f 61/292/492 60/293/493 123/294/494 +f 62/295/495 61/296/496 123/297/497 +f 43/298/498 62/299/499 123/300/500 +f 103/301/501 104/302/502 124/303/503 +f 104/304/504 105/305/505 124/306/506 +f 105/307/507 106/308/508 124/309/509 +f 106/310/510 107/311/511 124/312/512 +f 107/313/513 108/314/514 124/315/515 +f 108/316/516 109/317/517 124/318/518 +f 109/319/519 110/320/520 124/321/521 +f 110/322/522 111/323/523 124/324/524 +f 111/325/525 112/326/526 124/327/527 +f 112/328/528 113/329/529 124/330/530 +f 113/331/531 114/332/532 124/333/533 +f 114/334/534 115/335/535 124/336/536 +f 115/337/537 116/338/538 124/339/539 +f 116/340/540 117/341/541 124/342/542 +f 117/343/543 118/344/544 124/345/545 +f 118/346/546 119/347/547 124/348/548 +f 119/349/549 120/350/550 124/351/551 +f 120/352/552 121/353/553 124/354/554 +f 121/355/555 122/356/556 124/357/557 +f 122/358/558 103/359/559 124/360/560 diff --git a/build/assets/lamp.mtl b/build/assets/lamp.mtl new file mode 100644 index 0000000..c89145d --- /dev/null +++ b/build/assets/lamp.mtl @@ -0,0 +1,6 @@ +newmtl initialShadingGroup +illum 4 +Kd 0.50 0.50 0.50 +Ka 0.00 0.00 0.00 +Tf 1.00 1.00 1.00 +Ni 1.00 diff --git a/build/bundle.js b/build/bundle.js index 0690923..b8fc70e 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -79,11 +79,11 @@ var DEFAULT_GRID_WIDTH = 6; var DEFAULT_GRID_HEIGHT = 17; var DEFAULT_GRID_DEPTH = 6; - var DEFAULT_NUM_METABALLS = 10; + var DEFAULT_NUM_METABALLS = 7; var DEFAULT_MIN_RADIUS = 0.5; var DEFAULT_MAX_RADIUS = 1; var DEFAULT_MAX_SPEEDX = 0.005; - var DEFAULT_MAX_SPEEDY = 0.03; + var DEFAULT_MAX_SPEEDY = 0.3; var options = { lightColor: '#ffffff', lightIntensity: 1, ambient: '#111111', albedo: '#110000' }; var loaded = false; @@ -188,7 +188,7 @@ //scene.add(new THREE.AxisHelper(20)); var objLoader = new THREE.OBJLoader(); - var obj = objLoader.load('glass.obj', function (obj) { + var obj = objLoader.load(__webpack_require__(22), function (obj) { glassGeo = obj.children[0].geometry; var glass = new THREE.Mesh(glassGeo, GLASS_MAT); glass.translateX(-1.5); @@ -197,7 +197,7 @@ loaded = true; }); - var obj = objLoader.load('lamp.obj', function (obj) { + var obj = objLoader.load(__webpack_require__(23), function (obj) { lampGeo = obj.children[0].geometry; var lamp = new THREE.Mesh(lampGeo, METAL_MAT); lamp.translateX(-1.5); @@ -251,51 +251,40 @@ App.marchingCubes = new _marching_cubes2.default(App); } - function setupGUI(gui) {} - - // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage - - - // gui.add(App, 'isPaused').onChange(function(value) { - // App.isPaused = value; - // if (value) { - // App.marchingCubes.pause(); - // } else { - // App.marchingCubes.play(); - // } - // }); - - // gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) { - // App.config.numMetaballs = value; - // App.marchingCubes.init(App); - // }); - - // --- DEBUG --- - - // var debugFolder = gui.addFolder('Debug'); - // debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) { - // App.marchingCubes.showGrid = value; - // if (value) { - // App.marchingCubes.show(); - // } else { - // App.marchingCubes.hide(); - // } - // }); - - // debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) { - // App.marchingCubes.showSpheres = value; - // if (value) { - // for (var i = 0; i < App.config.numMetaballs; i++) { - // App.marchingCubes.balls[i].show(); - // } - // } else { - // for (var i = 0; i < App.config.numMetaballs; i++) { - // App.marchingCubes.balls[i].hide(); - // } - // } - // }); - // debugFolder.open(); + function setupGUI(gui) { + // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage + + gui.add(App.config, 'numMetaballs', 1, 10).step(1).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + + gui.add(App.config, 'minRadius', 0, 1).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + + gui.add(App.config, 'maxRadius', 1, 2).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + + gui.add(App.config, 'maxSpeedY', 0, 1).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + + gui.add(App.config, 'isolevel', 0, 2).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + + gui.add(App.config, 'gridRes', 1, 40).step(1).onChange(function (value) { + App.marchingCubes.reset(); + App.marchingCubes = new _marching_cubes2.default(App); + }); + } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate _framework2.default.init(onLoad, onUpdate); @@ -42663,7 +42652,7 @@ stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); - var gui = new _datGui2.default.GUI({ autoPlace: false }); + var gui = new _datGui2.default.GUI(); var framework = { gui: gui, @@ -48353,6 +48342,12 @@ this.setupMetaballs(); this.makeMesh(); } + }, { + key: 'reset', + value: function reset() { + this.scene.remove(this.mesh); + this.balls = [];balls = []; + } }, { key: 'i1toi3', @@ -48425,7 +48420,7 @@ pos = new THREE.Vector3(3, 3, 3); vx = 0; - vy = (Math.random() * 2 - 1) * this.maxSpeedY; + vy = (Math.random() * 2 - 1) * this.maxSpeedY / 10; vz = 0; vel = new THREE.Vector3(vx, vy, vz); @@ -49279,6 +49274,18 @@ module.exports = "uniform vec3 u_lightPos;\r\nuniform vec3 u_lightCol;\r\nuniform float u_lightIntensity;\r\n\r\nvarying vec3 f_position;\r\nvarying vec3 f_normal;\r\n\r\nvoid main() {\r\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\r\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\r\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\r\n}\r\n" +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__.p + "./assets/glass-5b14a7.obj"; + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__.p + "./assets/lamp-1bcc16.obj"; + /***/ } /******/ ]); //# sourceMappingURL=bundle.js.map \ No newline at end of file diff --git a/build/bundle.js.map b/build/bundle.js.map index 0f8563b..0cd8cd6 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 814670acf2567ec58054","webpack:///./src/main.js","webpack:///./src/textures.js","webpack:///./~/three/build/three.js","webpack:///./src/assets/silver.bmp","webpack:///./src/framework.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/three-orbit-controls/index.js","webpack:///./src/marching_cube_LUT.js","webpack:///./src/marching_cubes.js","webpack:///./src/metaball.js","webpack:///./src/inspect_point.js","webpack:///./src/shaders/lava-vert.glsl","webpack:///./src/shaders/lava-frag.glsl","webpack:///./index.html","webpack:///./~/three-obj-loader/dist/index.js","webpack:///./src/shaders/glass-vert.glsl","webpack:///./src/shaders/glass-frag.glsl","webpack:///./src/shaders/metal-vert.glsl","webpack:///./src/shaders/metal-frag.glsl"],"names":["require","THREE","OBJLoader","DEFAULT_VISUAL_DEBUG","DEFAULT_ISO_LEVEL","DEFAULT_GRID_RES","DEFAULT_GRID_WIDTH","DEFAULT_GRID_HEIGHT","DEFAULT_GRID_DEPTH","DEFAULT_NUM_METABALLS","DEFAULT_MIN_RADIUS","DEFAULT_MAX_RADIUS","DEFAULT_MAX_SPEEDX","DEFAULT_MAX_SPEEDY","options","lightColor","lightIntensity","ambient","albedo","loaded","red","Color","green","glassGeo","lampGeo","g_mat","uniforms","u_albedo","type","value","u_ambient","u_lightCol","u_lightIntensity","vertexShader","fragmentShader","m_mat","GLASS_MAT","MeshLambertMaterial","color","emissive","transparent","opacity","METAL_MAT","MeshPhongMaterial","App","marchingCubes","undefined","config","visualDebug","isolevel","gridRes","gridWidth","gridHeight","gridDepth","gridCellWidth","gridCellHeight","gridCellDepth","numMetaballs","minRadius","maxRadius","maxSpeedX","maxSpeedY","maxSpeedZ","camera","scene","renderer","isPaused","onLoad","framework","gui","stats","setClearColor","objLoader","obj","load","children","geometry","glass","Mesh","translateX","translateZ","add","lamp","setupCamera","setupLights","setupScene","setupGUI","cosine","a","b","c","d","t","Math","cos","PI","onUpdate","date","Date","sec","getSeconds","r","g","set","update","position","lookAt","Vector3","directionalLight","DirectionalLight","setHSL","multiplyScalar","init","silverTexture","Promise","resolve","reject","TextureLoader","texture","OrbitControls","callback","setMode","domElement","style","left","top","document","body","appendChild","GUI","autoPlace","window","addEventListener","Scene","PerspectiveCamera","innerWidth","innerHeight","WebGLRenderer","antialias","alpha","setPixelRatio","devicePixelRatio","setSize","controls","enableDamping","enableZoom","target","rotateSpeed","zoomSpeed","panSpeed","hasMoved","aspect","updateProjectionMatrix","tick","begin","render","end","requestAnimationFrame","EDGE_TABLE","Int32Array","TRI_TABLE","VISUAL_DEBUG","episolon","balls","l_mat","LAVA_MAT","ShaderMaterial","LAMBERT_WHITE","LAMBERT_GREEN","MeshBasicMaterial","WIREFRAME_MAT","LineBasicMaterial","linewidth","sample","point","isovalue","i","length","radius","distanceTo","pos","MarchingCubes","origin","halfCellWidth","halfCellHeight","halfCellDepth","res","res2","res3","voxels","showSpheres","showGrid","then","material","setupCells","setupMetaballs","makeMesh","i1","i3x","i3y","i3z","i3","x","y","z","i1toi3","i3toPos","voxel","Voxel","push","wireframe","mesh","vx","vy","vz","vel","matLambertWhite","maxRadiusTRippled","maxRadiusDoubled","random","neg","ball","forEach","center","corners","show","hide","updateLabel","clearLabel","updateMesh","geo","Geometry","dynamic","vertices","faces","count","vox_count","vANDn","polygonize","j","vertPositions","normals","k","vertNormals","Face3","verticesNeedUpdate","normalsNeedUpdate","elementsNeedUpdate","computeFaceNormals","makeInspectPoints","halfGridCellWidth","halfGridCellHeight","halfGridCellDepth","positions","Float32Array","indices","Uint16Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","BoxBufferGeometry","w","h","visible","posA","posB","lerpPos","lerpVectors","edges","points","vertexLerp","x0","x1","y0","y1","z0","z1","n","normalize","vertexList","normalList","faceList","corner","allVert","edgePoints","tri","vertex","getNormal","SPHERE_GEO","SphereBufferGeometry","Metaball","radius2","debug","scale","velocity","copy","POINT_MATERIAL","PointsMaterial","size","sizeAttenuation","InspectPoint","label","makeLabel","createElement","width","height","userSelect","cursor","fontSize","pointerEvents","screenPos","clone","project","innerHTML","toFixed"],"mappings":"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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,0BA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AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA,oEAAmE;;AAEnE;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IA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A;;AAEA,IAAG;;;;AAIH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AA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A;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;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A;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,m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AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,4CAA2C,OAAO;;AAElD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,SAAQ;;AAER;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,OAAO;;AAEjD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,2BAA2B;;AAE/C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,2BAA2B;;AAE/C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;AACA;AACA;;AAEA,6BAA4B;AAC5B,2BAA0B;;AAE1B;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,+CAA8C;AAC9C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,oCAAmC,QAAQ;;AAE3C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,0BAAyB;;AAEzB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kDAAiD,OAAO;;AAExD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAe,QAAQ;;AAEvB;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,mBAAmB;;AAEtC;;AAEA;;AAEA;;AAEA;;AAEA,0BAAyB,qCAAqC;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA,aAAY,OAAO;;AAEnB;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA,kDAAiD;AACjD;AACA;;AAEA;AACA;;AAEA,+FAA8F;AAC9F;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;AACA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sCAAsC;;AAE1D;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,4BAA2B;;AAE3B;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,6BAA4B;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,+EAA8E,kCAAkC;;AAEhH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,+CAA8C,OAAO;;AAErD;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,kDAAiD;;AAEjD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAQ;;AAER;;AAEA,OAAM;;AAEN,qDAAoD,OAAO;;AAE3D;AACA;;AAEA;;AAEA;;AAEA,kDAAiD;;AAEjD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAQ;;AAER;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,sBAAqB,oBAAoB;;AAEzC;;AAEA;;AAEA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,4EAA2E,kCAAkC;;AAE7G;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,iDAAgD,OAAO;;AAEvD;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,2CAA0C,OAAO;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB;AAChB;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,sCAAqC,OAAO;;AAE5C;;AAEA,qBAAoB,OAAO;;AAE3B;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAiC,OAAO;;AAExC,qBAAoB,OAAO;;AAE3B;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;;AAEA,8CAA6C,QAAQ;;AAErD,uBAAsB,OAAO;;AAE7B;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,OAAO;;AAEzC,sBAAqB,OAAO;;AAE5B;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;;AAEA,kCAAiC,OAAO;;AAExC,sBAAqB,OAAO;;AAE5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,eAAc,aAAa;;AAE3B;;AAEA,gBAAe,aAAa;;AAE5B;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,eAAc,YAAY;;AAE1B,gBAAe,YAAY;;AAE3B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,oBAAmB,oBAAoB;;AAEvC;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB,WAAW;;AAE3B;;AAEA;AACA;;AAEA;;AAEA,iBAAgB,WAAW;;AAE3B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,WAAW;;AAE1B,iBAAgB,0BAA0B;;AAE1C;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,yBAAyB;;AAE5C;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,yBAAyB;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,qBAAqB;;AAExC;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,2BAA0B,yBAAyB;;AAEnD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AA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EA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;A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A;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;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;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0FAAyF,4CAA4C;AACrI;;AAEA;AACA;AACA,8FAA6F,4CAA4C;AACzI;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;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CA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AA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;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB,gCAA+B;;AAE/B;AACA;AACA,qCAAoC;AACpC,mCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;;AAEzB;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;;AAEA;AACA,gBAAe;;AAEf;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA,sBAAqB;AACrB,qBAAoB;AACpB,mBAAkB;;AAElB,gBAAe;;AAEf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AA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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 814670acf2567ec58054","require('file-loader?name=[name].[ext]!../index.html');\r\nimport {silverTexture} from './textures'\r\n//import {quote} from './quote'\r\n// Credit:\r\n// http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/\r\n// http://paulbourke.net/geometry/polygonise/\r\n\r\nconst THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much\r\nconst OBJLoader = require('three-obj-loader');\r\nOBJLoader(THREE)\r\n\r\nimport Framework from './framework'\r\nimport LUT from './marching_cube_LUT.js'\r\nimport MarchingCubes from './marching_cubes.js'\r\n\r\nconst DEFAULT_VISUAL_DEBUG = false;\r\nconst DEFAULT_ISO_LEVEL = 1.0;\r\nconst DEFAULT_GRID_RES = 30;\r\nconst DEFAULT_GRID_WIDTH = 6;\r\nconst DEFAULT_GRID_HEIGHT = 17;\r\nconst DEFAULT_GRID_DEPTH = 6;\r\nconst DEFAULT_NUM_METABALLS = 10;\r\nconst DEFAULT_MIN_RADIUS = 0.5;\r\nconst DEFAULT_MAX_RADIUS = 1;\r\nconst DEFAULT_MAX_SPEEDX = 0.005;\r\nconst DEFAULT_MAX_SPEEDY = 0.03;\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'};\r\nvar loaded = false;\r\nvar red = new THREE.Color(1.0,0.0,0.0);\r\nvar green = new THREE.Color(0.0,1.0,0.0);\r\nvar glassGeo;\r\nvar lampGeo;\r\n\r\n// glass, emissive, iridescent\r\nvar g_mat = {\r\n uniforms: {\r\n u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/glass-vert.glsl'),\r\n fragmentShader: require('./shaders/glass-frag.glsl')\r\n};\r\n\r\n// metal\r\nvar m_mat = {\r\n uniforms: {\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/metal-vert.glsl'),\r\n fragmentShader: require('./shaders/metal-frag.glsl')\r\n};\r\n\r\n//const GLASS_MAT = new THREE.ShaderMaterial(g_mat);\r\nvar GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3});\r\nvar METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111});\r\n\r\nvar App = {\r\n //\r\n marchingCubes: undefined,\r\n config: {\r\n // Global control of all visual debugging.\r\n // This can be set to false to disallow any memory allocation of visual debugging components.\r\n // **Note**: If your application experiences performance drop, disable this flag.\r\n visualDebug: DEFAULT_VISUAL_DEBUG,\r\n\r\n // The isolevel for marching cubes\r\n isolevel: DEFAULT_ISO_LEVEL,\r\n\r\n // Grid resolution in each dimension. If gridRes = 4, then we have a 4x4x4 grid\r\n gridRes: DEFAULT_GRID_RES,\r\n\r\n // Total width of grid\r\n gridWidth: DEFAULT_GRID_WIDTH,\r\n\r\n gridHeight: DEFAULT_GRID_HEIGHT,\r\n\r\n gridDepth: DEFAULT_GRID_DEPTH,\r\n\r\n // Width of each voxel\r\n // Ideally, we want the voxel to be small (higher resolution)\r\n gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES,\r\n gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES,\r\n gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES,\r\n\r\n // Number of metaballs\r\n numMetaballs: DEFAULT_NUM_METABALLS,\r\n\r\n // Minimum radius of a metaball\r\n minRadius: DEFAULT_MIN_RADIUS,\r\n\r\n // Maxium radius of a metaball\r\n maxRadius: DEFAULT_MAX_RADIUS,\r\n\r\n // Maximum speed of a metaball\r\n maxSpeedX: DEFAULT_MAX_SPEEDX,\r\n maxSpeedY: DEFAULT_MAX_SPEEDY,\r\n maxSpeedZ: DEFAULT_MAX_SPEEDX, \r\n },\r\n\r\n // Scene's framework objects\r\n camera: undefined,\r\n scene: undefined,\r\n renderer: undefined,\r\n\r\n // Play/pause control for the simulation\r\n isPaused: false,\r\n color: 0xffffff\r\n};\r\n\r\n// called after the scene loads\r\nfunction onLoad(framework) {\r\n\r\n var {scene, camera, renderer, gui, stats} = framework;\r\n App.scene = scene;\r\n App.camera = camera;\r\n App.renderer = renderer;\r\n\r\n renderer.setClearColor( 0x111111 );\r\n //scene.add(new THREE.AxisHelper(20));\r\n\r\n var objLoader = new THREE.OBJLoader();\r\n var obj = objLoader.load('glass.obj', function(obj) {\r\n glassGeo = obj.children[0].geometry;\r\n var glass = new THREE.Mesh(glassGeo, GLASS_MAT);\r\n glass.translateX(-1.5);\r\n glass.translateZ(-1.5);\r\n App.scene.add(glass);\r\n loaded = true;\r\n });\r\n\r\n var obj = objLoader.load('lamp.obj', function(obj) {\r\n lampGeo = obj.children[0].geometry;\r\n var lamp = new THREE.Mesh(lampGeo, METAL_MAT);\r\n lamp.translateX(-1.5);\r\n lamp.translateZ(-1.5);\r\n App.scene.add(lamp);\r\n });\r\n\r\n setupCamera(App.camera);\r\n setupLights(App.scene);\r\n setupScene(App.scene);\r\n setupGUI(gui);\r\n}\r\n\r\nfunction cosine(a,b,c,d,t) {\r\n return a + b * Math.cos(2.0 * Math.PI * (c * t + d));\r\n}\r\n\r\n// called on frame updates\r\nfunction onUpdate(framework) {\r\n if (loaded) {\r\n var date = new Date();\r\n var sec = date.getSeconds();\r\n var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0);\r\n var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0);\r\n var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); \r\n GLASS_MAT.emissive.set(new THREE.Color(r,g,b));\r\n }\r\n if (App.marchingCubes) {\r\n App.marchingCubes.update();\r\n }\r\n}\r\n\r\nfunction setupCamera(camera) {\r\n // set camera position\r\n camera.position.set(25, 10, 25);\r\n camera.lookAt(new THREE.Vector3(8,0,-5));\r\n}\r\n\r\nfunction setupLights(scene) {\r\n\r\n // Directional light\r\n var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );\r\n directionalLight.color.setHSL(0.1, 1, 0.95);\r\n directionalLight.position.set(1, 10, 2);\r\n directionalLight.position.multiplyScalar(10);\r\n\r\n scene.add(directionalLight);\r\n}\r\n\r\nfunction setupScene(scene) {\r\n App.marchingCubes = new MarchingCubes(App);\r\n}\r\n\r\nfunction setupGUI(gui) {\r\n\r\n // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage\r\n\r\n\r\n // gui.add(App, 'isPaused').onChange(function(value) {\r\n // App.isPaused = value;\r\n // if (value) {\r\n // App.marchingCubes.pause();\r\n // } else {\r\n // App.marchingCubes.play();\r\n // }\r\n // });\r\n\r\n // gui.add(App.config, 'numMetaballs', 1, 10).onChange(function(value) {\r\n // App.config.numMetaballs = value;\r\n // App.marchingCubes.init(App);\r\n // });\r\n\r\n // --- DEBUG ---\r\n\r\n // var debugFolder = gui.addFolder('Debug');\r\n // debugFolder.add(App.marchingCubes, 'showGrid').onChange(function(value) {\r\n // App.marchingCubes.showGrid = value;\r\n // if (value) {\r\n // App.marchingCubes.show();\r\n // } else {\r\n // App.marchingCubes.hide();\r\n // }\r\n // });\r\n\r\n // debugFolder.add(App.marchingCubes, 'showSpheres').onChange(function(value) {\r\n // App.marchingCubes.showSpheres = value;\r\n // if (value) {\r\n // for (var i = 0; i < App.config.numMetaballs; i++) {\r\n // App.marchingCubes.balls[i].show();\r\n // }\r\n // } else {\r\n // for (var i = 0; i < App.config.numMetaballs; i++) {\r\n // App.marchingCubes.balls[i].hide();\r\n // }\r\n // }\r\n // });\r\n // debugFolder.open();\r\n}\r\n\r\n// when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate\r\nFramework.init(onLoad, onUpdate);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n// this file is just for convenience. it sets up loading the mario obj and texture\r\n\r\nconst THREE = require('three');\r\n\r\nexport var silverTexture = new Promise((resolve, reject) => {\r\n (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) {\r\n resolve(texture);\r\n })\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/textures.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*(\\S*)\\s*\\(/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tObject.assign( EventDispatcher.prototype, {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\tvar REVISION = '82';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar BlendingMode = {\n\t\tNoBlending: NoBlending,\n\t\tNormalBlending: NormalBlending,\n\t\tAdditiveBlending: AdditiveBlending,\n\t\tSubtractiveBlending: SubtractiveBlending,\n\t\tMultiplyBlending: MultiplyBlending,\n\t\tCustomBlending: CustomBlending\n\t};\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar TextureMapping = {\n\t\tUVMapping: UVMapping,\n\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t};\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar TextureWrapping = {\n\t\tRepeatWrapping: RepeatWrapping,\n\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t};\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar TextureFilter = {\n\t\tNearestFilter: NearestFilter,\n\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\tLinearFilter: LinearFilter,\n\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t};\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\trandom16: function () {\n\n\t\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\t\treturn Math.random();\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: TextureIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.sourceFile = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\tvar count = 0;\n\tfunction TextureIdCount() { return count++; }\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\t\t\tthis.w = attribute.array[ index + 3 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyProjection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 projection matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\t\t\tvar d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide\n\n\t\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;\n\t\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;\n\t\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix4( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeFrustum: function ( left, right, bottom, top, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakePerspective: function ( fov, aspect, near, far ) {\n\n\t\t\tvar ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 );\n\t\t\tvar ymin = - ymax;\n\t\t\tvar xmin = ymin * aspect;\n\t\t\tvar xmax = ymax * aspect;\n\n\t\t\treturn this.makeFrustum( xmin, xmax, ymin, ymax, near, far );\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\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}\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\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}\\n\";\n\n\tvar 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\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n float maxComponent = max( max( value.r, value.g ), value.b );\\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n M = ceil( M * 255.0 ) / 255.0;\\n return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float D = max( maxRange / maxRGB, 1.0 );\\n D = min( floor( D ) / 255.0, 1.0 );\\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n vec4 vResult;\\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n vResult.w = fract(Le);\\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n return 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 float Le = value.z * 255.0 + value.w;\\n vec3 Xp_Y_XYZp;\\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\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\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color = pointLight.color;\\n\\t\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\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_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\\t#include \\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\\t#include \\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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar 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};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\\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_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar 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\";\n\n\tvar 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}\\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_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\";\n\n\tvar 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 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\\t\\t\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n return 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 return ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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 boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n return 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 color *= toneMappingExposure;\\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n color = max( vec3( 0.0 ), color - 0.004 );\\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar 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\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\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\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\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\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse = vec3( 0.0 );\\n\\treflectedLight.directSpecular = vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse = diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular = vec3( 0.0 );\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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 \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\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 \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\n}\\n\";\n\n\tvar normal_vert = \"varying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvNormal = normalize( normalMatrix * normal );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( (value && value.isColor) ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular : { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity : { value: 1 }, // temporary\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\n\t\t\t\t{\n\t\t\t\t\tscale : { value: 1 },\n\t\t\t\t\tdashSize : { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: {\n\n\t\t\t\topacity : { value: 1.0 }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\n\t\t\t\tlightPos: { value: new Vector3() }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\tShaderLib.standard.uniforms,\n\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t point.y < this.min.y || point.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyProjection( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( (fog && fog.isFog) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( (fog && fog.isFogExp2) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: MaterialIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( (currentValue && currentValue.isColor) ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( (currentValue && currentValue.isVector3) && (newValue && newValue.isVector3) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( (this.color && this.color.isColor) ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();\n\t\t\tif ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\n\t\t\tif ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.bumpMap && this.bumpMap.isTexture) ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( (this.normalMap && this.normalMap.isTexture) ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( (this.displacementMap && this.displacementMap.isTexture) ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.envMap && this.envMap.isTexture) ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\tvar count$1 = 0;\n\tfunction MaterialIdCount() { return count$1++; }\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tthis.makeEmpty();\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tvar array, offset, stride;\n\n\t\t\t\t\t\t\t\tif ( (attribute && attribute.isInterleavedBufferAttribute) ) {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.data.array;\n\t\t\t\t\t\t\t\t\toffset = attribute.offset;\n\t\t\t\t\t\t\t\t\tstride = attribute.data.stride;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.array;\n\t\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\t\tstride = 3;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor ( var i = offset, il = array.length; i < il; i += stride ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromArray( array, i );\n\t\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\t\t point.y < this.min.y || point.y > this.max.y ||\n\t\t\t\t\t point.z < this.min.z || point.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&\n\t\t\t\t ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\t\t box.max.z < this.min.z || box.min.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// 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.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box = new Box3();\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix3( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( (matrix && matrix.isMatrix4) ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.clearColor( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( (light && light.isPointLight) ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( (shadow && shadow.isSpotLightShadow) ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( (material && material.isMultiMaterial) ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: Object3DIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function(){}; \n\t\tthis.onAfterRender = function(){};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype, {\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( (object && object.isObject3D) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\tvar count$2 = 0;\n\tfunction Object3DIdCount() { return count$2++; }\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int16Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint16Array( array ), itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int32Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float64Array( array ), itemSize );\n\n\t}\n\n\t// Deprecated\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [ [] ];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype, {\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( (geometry && geometry.isGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( (mesh && mesh.isMesh) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\tvar dupIndex = - 1;\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tdupIndex = n;\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [ [] ];\n\t\t\tthis.colors = [];\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( var i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( var i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( var k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tvar count$3 = 0;\n\tfunction GeometryIdCount() { return count$3++; }\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'DirectGeometry';\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tcomputeBoundingBox: Geometry.prototype.computeBoundingBox,\n\t\tcomputeBoundingSphere: Geometry.prototype.computeBoundingSphere,\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tthis.index = index;\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( (attribute && attribute.isBufferAttribute) === false && (attribute && attribute.isInterleavedBufferAttribute) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToVector3Array( position.array );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToVector3Array( normal.array );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isPoints) || (object && object.isLine) ) {\n\n\t\t\t\tvar positions = new Float32Attribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32Attribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32Attribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( (object && object.isMesh) ) {\n\n\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isMesh) ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32Attribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32Attribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar positions = this.attributes.position.array;\n\n\t\t\tif ( positions !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromArray( positions );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar positions = this.attributes.position;\n\n\t\t\t\tif ( positions ) {\n\n\t\t\t\t\tvar array = positions.array;\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromArray( array );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i += 3 ) {\n\n\t\t\t\t\t\tvector.fromArray( array, i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC,\n\n\t\t\t\tpA = new Vector3(),\n\t\t\t\tpB = new Vector3(),\n\t\t\t\tpC = new Vector3(),\n\n\t\t\t\tcb = new Vector3(),\n\t\t\t\tab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( (geometry && geometry.isBufferGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {\n\n\t\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\t\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\t\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar uvs, intersection;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( attributes.uv !== undefined ) {\n\n\t\t\t\t\t\tuvs = attributes.uv.array;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = indices[ i ];\n\t\t\t\t\t\t\tb = indices[ i + 1 ];\n\t\t\t\t\t\t\tc = indices[ i + 2 ];\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length; i < l; i += 9 ) {\n\n\t\t\t\t\t\t\ta = i / 3;\n\t\t\t\t\t\t\tb = a + 1;\n\t\t\t\t\t\t\tc = a + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = (material && material.isMultiMaterial);\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );\n\t\tvar indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\t\tvar numberOfVertices = 0;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount( w, h, d ) {\n\n\t\t\tvar vertices = 0;\n\n\t\t\t// calculate the amount of vertices for each side (plane)\n\t\t\tvertices += (w + 1) * (h + 1) * 2; // xy\n\t\t\tvertices += (w + 1) * (d + 1) * 2; // xz\n\t\t\tvertices += (d + 1) * (h + 1) * 2; // zy\n\n\t\t\treturn vertices;\n\n\t\t}\n\n\t\tfunction calculateIndexCount( w, h, d ) {\n\n\t\t\tvar index = 0;\n\n\t\t\t// calculate the amount of squares for each side\n\t\t\tindex += w * h * 2; // xy\n\t\t\tindex += w * d * 2; // xz\n\t\t\tindex += d * h * 2; // zy\n\n\t\t\treturn index * 6; // two triangles per square => six vertices per square\n\n\t\t}\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth\t= width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\t\t\t\t\tvertices[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\t\t\t\t\tnormals[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tnormals[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tnormals[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// uvs\n\t\t\t\t\tuvs[ uvBufferOffset ] = ix / gridX;\n\t\t\t\t\tuvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\t\tuvBufferOffset += 2;\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\t// indices\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tindexBufferOffset += 6;\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar vertices = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar normals = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar uvs = new Float32Array( gridX1 * gridY1 * 2 );\n\n\t\tvar offset = 0;\n\t\tvar offset2 = 0;\n\n\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices[ offset ] = x;\n\t\t\t\tvertices[ offset + 1 ] = - y;\n\n\t\t\t\tnormals[ offset + 2 ] = 1;\n\n\t\t\t\tuvs[ offset2 ] = ix / gridX;\n\t\t\t\tuvs[ offset2 + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\toffset += 3;\n\t\t\t\toffset2 += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\toffset = 0;\n\n\t\tvar indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );\n\n\t\tfor ( var iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( var ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices[ offset ] = a;\n\t\t\t\tindices[ offset + 1 ] = b;\n\t\t\t\tindices[ offset + 2 ] = d;\n\n\t\t\t\tindices[ offset + 3 ] = b;\n\t\t\t\tindices[ offset + 4 ] = c;\n\t\t\t\tindices[ offset + 5 ] = d;\n\n\t\t\t\toffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makeFrustum(\n\t\t\t\t\tleft, left + width, top - height, top, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( (position && position.isInterleavedBufferAttribute) ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( 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\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( (map && map.isTexture) ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( (map && map.isWebGLRenderTarget) ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\t\t\tvar position = attributes.position;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar edges = {};\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;\n\t\t\tvar attribute = new BufferAttribute( new TypeArray( indices ), 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true;\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true;\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( (renderTarget && renderTarget.isWebGLRenderTargetCube) ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = (texture && texture.isCompressedTexture);\n\t\t\t\t\tvar isDataTexture = (texture.image[ 0 ] && texture.image[ 0 ].isDataTexture);\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( (texture && texture.isDepthTexture) ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( (texture && texture.isDataTexture) ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( (texture && texture.isCompressedTexture) ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( (renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture) ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a ) {\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tclearColor( 0, 0, 0, 1 );\n\t\t\tclearDepth( 1 );\n\t\t\tclearStencil( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tgl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction clearColor( r, g, b, a ) {\n\n\t\t\tcolorBuffer.setClear( r, g, b, a );\n\n\t\t}\n\n\t\tfunction clearDepth( depth ) {\n\n\t\t\tdepthBuffer.setClear( depth );\n\n\t\t}\n\n\t\tfunction clearStencil( stencil ) {\n\n\t\t\tstencilBuffer.setClear( stencil );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tclearColor: clearColor,\n\t\t\tclearDepth: clearDepth,\n\t\t\tclearStencil: clearStencil,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t// internal state cache\n\n\t\t_currentProgram = null,\n\t\t_currentRenderTarget = null,\n\t\t_currentFramebuffer = null,\n\t\t_currentMaterialId = - 1,\n\t\t_currentGeometryProgram = '',\n\t\t_currentCamera = null,\n\n\t\t_currentScissor = new Vector4(),\n\t\t_currentScissorTest = null,\n\n\t\t_currentViewport = new Vector4(),\n\n\t\t//\n\n\t\t_usedTextureUnits = 0,\n\n\t\t//\n\n\t\t_clearColor = new Color( 0x000000 ),\n\t\t_clearAlpha = 0,\n\n\t\t_width = _canvas.width,\n\t\t_height = _canvas.height,\n\n\t\t_pixelRatio = 1,\n\n\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t_scissorTest = false,\n\n\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t// frustum\n\n\t\t_frustum = new Frustum(),\n\n\t\t// clipping\n\n\t\t_clipping = new WebGLClipping(),\n\t\t_clippingEnabled = false,\n\t\t_localClippingEnabled = false,\n\n\t\t_sphere = new Sphere(),\n\n\t\t// camera matrices cache\n\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_vector3 = new Vector3(),\n\n\t\t// light arrays cache\n\n\t\t_lights = {\n\n\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\tshadows: []\n\n\t\t},\n\n\t\t// info\n\n\t\t_infoRender = {\n\n\t\t\tcalls: 0,\n\t\t\tvertices: 0,\n\t\t\tfaces: 0,\n\t\t\tpoints: 0\n\n\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\t\tvar backgroundCamera2 = new PerspectiveCamera();\n\t\tvar backgroundPlaneMesh = new Mesh(\n\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t);\n\t\tvar backgroundBoxShader = ShaderLib[ 'cube' ];\n\t\tvar backgroundBoxMesh = new Mesh(\n\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\tnew ShaderMaterial( {\n\t\t\t\tuniforms: backgroundBoxShader.uniforms,\n\t\t\t\tvertexShader: backgroundBoxShader.vertexShader,\n\t\t\t\tfragmentShader: backgroundBoxShader.fragmentShader,\n\t\t\t\tside: BackSide,\n\t\t\t\tdepthTest: false,\n\t\t\t\tdepthWrite: false,\n\t\t\t\tfog: false\n\t\t\t} )\n\t\t);\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction glClearColor( r, g, b, a ) {\n\n\t\t\tif ( _premultipliedAlpha === true ) {\n\n\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t}\n\n\t\t\tstate.clearColor( r, g, b, a );\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t ! material.isMeshStandardMaterial &&\n\t\t\t\t material.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar type = _gl.FLOAT;\n\t\t\t\t\t\tvar array = geometryAttribute.array;\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\n\t\t\t\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.FLOAT;\n\n\t\t\t\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.BYTE;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_BYTE;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\t\t\t\t\t\tvar buffer = objects.getAttributeBuffer( geometryAttribute );\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tglClearColor( background.r, background.g, background.b, 1 );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tbackgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t ! material.isRawShaderMaterial ||\n\t\t\t material.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes || \n\t \t\t\t\t materialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isShaderMaterial ||\n\t\t\t\t material.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\tm_uniforms.opacity.value = material.opacity;\n\n\t\t\t\t}\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\tr = 0, g = 0, b = 0,\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\tdistance,\n\t\t\tshadowMap,\n\n\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\t p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone( skin ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t\tthis.skin = skin;\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.skin = source.skin;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone( this );\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( (this.geometry && this.geometry.isGeometry) ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.type = type !== undefined ? type : UnsignedShortType;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar numEdges = 0;\n\n\t\t\t// allocate maximal size\n\t\t\tvar edges = new Uint32Array( 6 * faces.length );\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\tvar vertex = vertices[ edges [ 2 * i + j ] ];\n\n\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\tcoords[ index + 0 ] = vertex.x;\n\t\t\t\t\tcoords[ index + 1 ] = vertex.y;\n\t\t\t\t\tcoords[ index + 2 ] = vertex.z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// Indexed BufferGeometry\n\n\t\t\t\tvar indices = geometry.index.array;\n\t\t\t\tvar vertices = geometry.attributes.position;\n\t\t\t\tvar groups = geometry.groups;\n\t\t\t\tvar numEdges = 0;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.length );\n\n\t\t\t\t}\n\n\t\t\t\t// allocate maximal size\n\t\t\t\tvar edges = new Uint32Array( 2 * indices.length );\n\n\t\t\t\tfor ( var o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tvar group = groups[ o ];\n\n\t\t\t\t\tvar start = group.start;\n\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices[ i + j ];\n\t\t\t\t\t\t\tedge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];\n\t\t\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\t\tvar index2 = edges[ 2 * i + j ];\n\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices.getX( index2 );\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices.getY( index2 );\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices.getZ( index2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tvar vertices = geometry.attributes.position.array;\n\t\t\t\tvar numEdges = vertices.length / 3;\n\t\t\t\tvar numTris = numEdges / 3;\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numTris; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\tvar index = 18 * i + 6 * j;\n\n\t\t\t\t\t\tvar index1 = 9 * i + 3 * j;\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices[ index1 ];\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices[ index1 + 1 ];\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices[ index1 + 2 ];\n\n\t\t\t\t\t\tvar index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tcoords[ index + 3 ] = vertices[ index2 ];\n\t\t\t\t\t\tcoords[ index + 4 ] = vertices[ index2 + 1 ];\n\t\t\t\t\t\tcoords[ index + 5 ] = vertices[ index2 + 2 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// generate vertices and uvs\n\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j, p;\n\t\tvar u, v;\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tv = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tu = j / slices;\n\n\t\t\t\tp = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tvar indices = [];\n\t\tvar a, b, c, d;\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\ta = i * sliceCount + j;\n\t\t\t\tb = i * sliceCount + j + 1;\n\t\t\t\tc = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\td = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', Float32Attribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0 ; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols ; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius,detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t *\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar i, j, index = 0, indexOffset = 0;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\tuv.y = j / radialSegments;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\n\t\t// helper variables\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices[ vertexBufferOffset ] = vertex.x;\n\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vertex.y;\n\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vertex.z;\n\n\t\t\t\t// this vector is used to calculate the normal\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\n\t\t\t\t// normal\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals[ vertexBufferOffset ] = normal.x;\n\t\t\t\tnormals[ vertexBufferOffset + 1 ] = normal.y;\n\t\t\t\tnormals[ vertexBufferOffset + 2 ] = normal.z;\n\n\t\t\t\t// uv\n\t\t\t\tuvs[ uvBufferOffset ] = i / tubularSegments;\n\t\t\t\tuvs[ uvBufferOffset + 1 ] = j / radialSegments;\n\n\t\t\t\t// update offsets\n\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\tuvBufferOffset += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t// face two\n\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t// update offset\n\t\t\t\tindexBufferOffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// 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.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t},\n\n\t\t// Bezier Curves formulas obtained from\n\t\t// http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n\t\t// Quad Bezier Functions\n\n\t\tb2: ( function () {\n\n\t\t\tfunction b2p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p1( t, p ) {\n\n\t\t\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p2( t, p ) {\n\n\t\t\t\treturn t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b2( t, p0, p1, p2 ) {\n\n\t\t\t\treturn b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\t// Cubic Bezier Functions\n\n\t\tb3: ( function () {\n\n\t\t\tfunction b3p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p1( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * k * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p2( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * t * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p3( t, p ) {\n\n\t\t\t\treturn t * t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b3( t, p0, p1, p2, p3 ) {\n\n\t\t\t\treturn b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( (font && font.isFont) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * based on THREE.SphereGeometry\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );\n\n\t\tvar positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\tvar index = 0, vertices = [], normal = new Vector3();\n\n\t\tfor ( var y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = y / heightSegments;\n\n\t\t\tfor ( var x = 0; x <= widthSegments; x ++ ) {\n\n\t\t\t\tvar u = x / widthSegments;\n\n\t\t\t\tvar px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvar py = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvar pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tnormal.set( px, py, pz ).normalize();\n\n\t\t\t\tpositions.setXYZ( index, px, py, pz );\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\tverticesRow.push( index );\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tvertices.push( verticesRow );\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var y = 0; y < heightSegments; y ++ ) {\n\n\t\t\tfor ( var x = 0; x < widthSegments; x ++ ) {\n\n\t\t\t\tvar v1 = vertices[ y ][ x + 1 ];\n\t\t\t\tvar v2 = vertices[ y ][ x ];\n\t\t\t\tvar v3 = vertices[ y + 1 ][ x ];\n\t\t\t\tvar v4 = vertices[ y + 1 ][ x + 1 ];\n\n\t\t\t\tif ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );\n\t\t\t\tif ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', positions );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 );\n\t\tvar indexCount = thetaSegments * phiSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// some helper variables\n\t\tvar index = 0, indexOffset = 0, segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\t// values are generate from the inside of the ring to the outside\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, 0, 1 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex++;\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\t // points - to create a closed torus, one must use a set of points\n\t // like so: [ a, b, c, d, a ], see first is the same as last.\n\t // segments - the number of circumference segments to create\n\t // phiStart - the starting radian\n\t // phiLength - the radian (0 to 2PI) range of the lathed section\n\t // 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( segments + 1 ) * points.length;\n\t\tvar indexCount = segments * points.length * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar index = 0, indexOffset = 0, base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t} // next row\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t *\n\t * Creates a one-sided polygonal geometry from a path shape. Similar to\n\t * ExtrudeGeometry.\n\t *\n\t * parameters = {\n\t *\n\t *\tcurveSegments: , // number of points on the curves. NOT USED AT THE MOMENT.\n\t *\n\t *\tmaterial: // material index for front and back faces\n\t *\tuvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ShapeGeometry( shapes, options ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( Array.isArray( shapes ) === false ) shapes = [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * Add an array of shapes to THREE.ShapeGeometry.\n\t */\n\tShapeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tfor ( var i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tthis.addShape( shapes[ i ], options );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.\n\t */\n\tShapeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tif ( options === undefined ) options = {};\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar material = options.material;\n\t\tvar uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;\n\n\t\t//\n\n\t\tvar i, l, hole;\n\n\t\tvar shapesOffset = this.vertices.length;\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe...\n\n\t\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\t\thole = holes[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( hole ) ) {\n\n\t\t\t\t\tholes[ i ] = hole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false;\n\n\t\t}\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t// Vertices\n\n\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\thole = holes[ i ];\n\t\t\tvertices = vertices.concat( hole );\n\n\t\t}\n\n\t\t//\n\n\t\tvar vert, vlen = vertices.length;\n\t\tvar face, flen = faces.length;\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = vertices[ i ];\n\n\t\t\tthis.vertices.push( new Vector3( vert.x, vert.y, 0 ) );\n\n\t\t}\n\n\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\tface = faces[ i ];\n\n\t\t\tvar a = face[ 0 ] + shapesOffset;\n\t\t\tvar b = face[ 1 ] + shapesOffset;\n\t\t\tvar c = face[ 2 ] + shapesOffset;\n\n\t\t\tthis.faces.push( new Face3( a, b, c, null, null, material ) );\n\t\t\tthis.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tvar geometry2;\n\n\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar vertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tvar key = edge.toString();\n\n\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\thash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\thash[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar coords = [];\n\n\t\tfor ( var key in hash ) {\n\n\t\t\tvar h = hash[ key ];\n\n\t\t\tif ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = vertices[ h.vert1 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t\tvertex = vertices[ h.vert2 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) );\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// used to calculate buffer length\n\n\t\tvar nbCap = 0;\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) nbCap ++;\n\t\t\tif ( radiusBottom > 0 ) nbCap ++;\n\n\t\t}\n\n\t\tvar vertexCount = calculateVertexCount();\n\t\tvar indexCount = calculateIndexCount();\n\n\t\t// buffers\n\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\n\t\tvar index = 0,\n\t\t indexOffset = 0,\n\t\t indexArray = [],\n\t\t halfHeight = height / 2;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount() {\n\n\t\t\tvar count = ( radialSegments + 1 ) * ( heightSegments + 1 );\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap );\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction calculateIndexCount() {\n\n\t\t\tvar count = radialSegments * heightSegments * 2 * 3;\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += radialSegments * nbCap * 3;\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\t\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\t\t\t\t\tindexRow.push( index );\n\n\t\t\t\t\t// increase index\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\tvar i1 = indexArray[ y ][ x ];\n\t\t\t\t\tvar i2 = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar i3 = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar i4 = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices.setX( indexOffset, i1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i3 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// update counters\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = 0.5;\n\t\t\t\tuv.y = 0.5;\n\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t}\n\n\t\t\t\t// update counters\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tvar vertices = segments + 2;\n\n\t\tvar positions = new Float32Array( vertices * 3 );\n\t\tvar normals = new Float32Array( vertices * 3 );\n\t\tvar uvs = new Float32Array( vertices * 2 );\n\n\t\t// center data is already zero, but need to set a few extras\n\t\tnormals[ 2 ] = 1.0;\n\t\tuvs[ 0 ] = 0.5;\n\t\tuvs[ 1 ] = 0.5;\n\n\t\tfor ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\tpositions[ i ] = radius * Math.cos( segment );\n\t\t\tpositions[ i + 1 ] = radius * Math.sin( segment );\n\n\t\t\tnormals[ i + 2 ] = 1; // normal z\n\n\t\t\tuvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;\n\t\t\tuvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry,\n\t\tBoxGeometry: BoxGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib[ \"lights\" ],\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = materials instanceof Array ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction XHRLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( XHRLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[1];\n\t\t\t\tvar isBase64 = !!dataUriRegexResult[2];\n\t\t\t\tvar data = dataUriRegexResult[3];\n\n\t\t\t\tdata = window.decodeURIComponent(data);\n\n\t\t\t\tif( isBase64 ) {\n\t\t\t\t\tdata = window.atob(data);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { \"type\" : mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tvar DataTextureLoader = BinaryTextureLoader;\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( BinaryTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\t\t\timage.onload = function () {\n\n\t\t\t\timage.onload = null;\n\n\t\t\t\tURL.revokeObjectURL( image.src );\n\n\t\t\t\tif ( onLoad ) onLoad( image );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t};\n\t\t\timage.onerror = onError;\n\n\t\t\tif ( url.indexOf( 'data:' ) === 0 ) {\n\n\t\t\t\timage.src = url;\n\n\t\t\t} else {\n\n\t\t\t\tvar loader = new XHRLoader();\n\t\t\t\tloader.setPath( this.path );\n\t\t\t\tloader.setResponseType( 'blob' );\n\t\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\t\tloader.load( url, function ( blob ) {\n\n\t\t\t\t\timage.src = URL.createObjectURL( blob );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( light ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true,\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function() {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function() {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function( timeOffset ) {\n\n\t\t\tif( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function( timeScale ) {\n\n\t\t\tif( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== -1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to , 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function() {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function() {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number',\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max(\n\t\t\t\t\t\tduration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0;\n\t\t\t\t\t\t\t\tm !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack(\n\t\t\t\t\t\t\t\t'.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader ( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tscope.parse( JSON.parse( text ), onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.SplineCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = 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\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\t// TODO: Transformation for Curves?\n\n\t/**************************************************************\n\t *\t3D Curves\n\t **************************************************************/\n\n\t// A Factory method for creating new curve subclasses\n\n\tCurve.create = function ( constructor, getPointFunc ) {\n\n\t\tconstructor.prototype = Object.create( Curve.prototype );\n\t\tconstructor.prototype.constructor = constructor;\n\t\tconstructor.prototype.getPoint = getPointFunc;\n\n\t\treturn constructor;\n\n\t};\n\n\t/**************************************************************\n\t *\tLine\n\t **************************************************************/\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**************************************************************\n\t *\tEllipse curve\n\t **************************************************************/\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar CurveUtils = {\n\n\t\ttangentQuadraticBezier: function ( t, p0, p1, p2 ) {\n\n\t\t\treturn 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );\n\n\t\t},\n\n\t\t// Puay Bing, thanks for helping with this derivative!\n\n\t\ttangentCubicBezier: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\treturn - 3 * p0 * ( 1 - t ) * ( 1 - t ) +\n\t\t\t\t3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +\n\t\t\t\t6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +\n\t\t\t\t3 * t * t * p3;\n\n\t\t},\n\n\t\ttangentSpline: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\t// To check if my formulas are correct\n\n\t\t\tvar h00 = 6 * t * t - 6 * t; \t// derived from 2t^3 − 3t^2 + 1\n\t\t\tvar h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t\n\t\t\tvar h01 = - 6 * t * t + 6 * t; \t// − 2t3 + 3t2\n\t\t\tvar h11 = 3 * t * t - 2 * t;\t// t3 − t2\n\n\t\t\treturn h00 + h10 + h01 + h11;\n\n\t\t},\n\n\t\t// Catmull-Rom\n\n\t\tinterpolate: function( p0, p1, p2, p3, t ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t * t2;\n\t\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t};\n\n\t/**************************************************************\n\t *\tSpline curve\n\t **************************************************************/\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\treturn new Vector2(\n\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight )\n\t\t);\n\n\t};\n\n\t/**************************************************************\n\t *\tCubic Bezier curve\n\t **************************************************************/\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b3 = ShapeUtils.b3;\n\n\t\treturn new Vector2(\n\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t);\n\n\t};\n\n\tCubicBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentCubicBezier = CurveUtils.tangentCubicBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\ttangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t).normalize();\n\n\t};\n\n\t/**************************************************************\n\t *\tQuadratic Bezier curve\n\t **************************************************************/\n\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b2 = ShapeUtils.b2;\n\n\t\treturn new Vector2(\n\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t);\n\n\t};\n\n\n\tQuadraticBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\ttangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t).normalize();\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t *\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\n\t// minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\tfunction ShapePath() {\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\t}\n\n\tShapePath.prototype = {\n\t\tmoveTo: function ( x, y ) {\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push(this.currentPath);\n\t\t\tthis.currentPath.moveTo( x, y );\n\t\t},\n\t\tlineTo: function ( x, y ) {\n\t\t\tthis.currentPath.lineTo( x, y );\n\t\t},\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\t\t},\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\t\t},\n\t\tsplineThru: function ( pts ) {\n\t\t\tthis.currentPath.splineThru( pts );\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar offset = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar ret = createPath( chars[ i ], scale, offset );\n\t\t\t\t\toffset += ret.offset;\n\n\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offset ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3;\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb2( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tb2( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb3( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tb3( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offset: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tfunction getAudioContext() {\n\n\t\tif ( context === undefined ) {\n\n\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn context;\n\n\t}\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = getAudioContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = getAudioContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\t\tthis.source = this.context.createBufferSource();\n\t\tthis.source.onended = this.onEnded.bind( this );\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.source.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.source.buffer;\n\t\t\tsource.loop = this.source.loop;\n\t\t\tsource.onended = this.source.onended;\n\t\t\tsource.start( 0, this.startTime );\n\t\t\tsource.playbackRate.value = this.playbackRate;\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.value = this.playbackRate;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.source.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.loop = value;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\t\t\tmixFunction = this._slerp;\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\n\t\t\t\tbufferType = Array,\t\tmixFunction = this._select;\t\tbreak;\n\n\t\t\tdefault:\t\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( (root && root.isAnimationObjectGroup) ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:\\w+[\\/:])*)(\\w+)?(?:\\.(\\w+)(?:\\[(.+)\\])?)?\\.(\\w+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tvar knownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis.loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype, {\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function() {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function() {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function() {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function() {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Spline from Tween.js, slightly optimized (and trashed)\n\t * http://sole.github.com/tween.js/examples/05_spline.html\n\t *\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Spline( points ) {\n\n\t\tthis.points = points;\n\n\t\tvar c = [], v3 = { x: 0, y: 0, z: 0 },\n\t\tpoint, intPoint, weight, w2, w3,\n\t\tpa, pb, pc, pd;\n\n\t\tthis.initFromArray = function ( a ) {\n\n\t\t\tthis.points = [];\n\n\t\t\tfor ( var i = 0; i < a.length; i ++ ) {\n\n\t\t\t\tthis.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getPoint = function ( k ) {\n\n\t\t\tpoint = ( this.points.length - 1 ) * k;\n\t\t\tintPoint = Math.floor( point );\n\t\t\tweight = point - intPoint;\n\n\t\t\tc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;\n\t\t\tc[ 1 ] = intPoint;\n\t\t\tc[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;\n\t\t\tc[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;\n\n\t\t\tpa = this.points[ c[ 0 ] ];\n\t\t\tpb = this.points[ c[ 1 ] ];\n\t\t\tpc = this.points[ c[ 2 ] ];\n\t\t\tpd = this.points[ c[ 3 ] ];\n\n\t\t\tw2 = weight * weight;\n\t\t\tw3 = weight * w2;\n\n\t\t\tv3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );\n\t\t\tv3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );\n\t\t\tv3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );\n\n\t\t\treturn v3;\n\n\t\t};\n\n\t\tthis.getControlPointsArray = function () {\n\n\t\t\tvar i, p, l = this.points.length,\n\t\t\t\tcoords = [];\n\n\t\t\tfor ( i = 0; i < l; i ++ ) {\n\n\t\t\t\tp = this.points[ i ];\n\t\t\t\tcoords[ i ] = [ p.x, p.y, p.z ];\n\n\t\t\t}\n\n\t\t\treturn coords;\n\n\t\t};\n\n\t\t// approximate length by summing linear segments\n\n\t\tthis.getLength = function ( nSubDivisions ) {\n\n\t\t\tvar i, index, nSamples, position,\n\t\t\t\tpoint = 0, intPoint = 0, oldIntPoint = 0,\n\t\t\t\toldPosition = new Vector3(),\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tchunkLengths = [],\n\t\t\t\ttotalLength = 0;\n\n\t\t\t// first point has 0 length\n\n\t\t\tchunkLengths[ 0 ] = 0;\n\n\t\t\tif ( ! nSubDivisions ) nSubDivisions = 100;\n\n\t\t\tnSamples = this.points.length * nSubDivisions;\n\n\t\t\toldPosition.copy( this.points[ 0 ] );\n\n\t\t\tfor ( i = 1; i < nSamples; i ++ ) {\n\n\t\t\t\tindex = i / nSamples;\n\n\t\t\t\tposition = this.getPoint( index );\n\t\t\t\ttmpVec.copy( position );\n\n\t\t\t\ttotalLength += tmpVec.distanceTo( oldPosition );\n\n\t\t\t\toldPosition.copy( position );\n\n\t\t\t\tpoint = ( this.points.length - 1 ) * index;\n\t\t\t\tintPoint = Math.floor( point );\n\n\t\t\t\tif ( intPoint !== oldIntPoint ) {\n\n\t\t\t\t\tchunkLengths[ intPoint ] = totalLength;\n\t\t\t\t\toldIntPoint = intPoint;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// last point ends with total length\n\n\t\t\tchunkLengths[ chunkLengths.length ] = totalLength;\n\n\t\t\treturn { chunks: chunkLengths, total: totalLength };\n\n\t\t};\n\n\t\tthis.reparametrizeByArcLength = function ( samplingCoef ) {\n\n\t\t\tvar i, j,\n\t\t\t\tindex, indexCurrent, indexNext,\n\t\t\t\trealDistance,\n\t\t\t\tsampling, position,\n\t\t\t\tnewpoints = [],\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tsl = this.getLength();\n\n\t\t\tnewpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );\n\n\t\t\tfor ( i = 1; i < this.points.length; i ++ ) {\n\n\t\t\t\t//tmpVec.copy( this.points[ i - 1 ] );\n\t\t\t\t//linearDistance = tmpVec.distanceTo( this.points[ i ] );\n\n\t\t\t\trealDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];\n\n\t\t\t\tsampling = Math.ceil( samplingCoef * realDistance / sl.total );\n\n\t\t\t\tindexCurrent = ( i - 1 ) / ( this.points.length - 1 );\n\t\t\t\tindexNext = i / ( this.points.length - 1 );\n\n\t\t\t\tfor ( j = 1; j < sampling - 1; j ++ ) {\n\n\t\t\t\t\tindex = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );\n\n\t\t\t\t\tposition = this.getPoint( index );\n\t\t\t\t\tnewpoints.push( tmpVec.copy( position ).clone() );\n\n\t\t\t\t}\n\n\t\t\t\tnewpoints.push( tmpVec.copy( this.points[ i ] ).clone() );\n\n\t\t\t}\n\n\t\t\tthis.points = newpoints;\n\n\t\t};\n\n\t\t// Catmull-Rom\n\n\t\tfunction interpolate( p0, p1, p2, p3, t, t2, t3 ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5,\n\t\t\t\tv1 = ( p3 - p1 ) * 0.5;\n\n\t\t\treturn ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new Geometry();\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.colors.push( new Color( 0, 0, 1 ) );\n\t\t\t\tgeometry.colors.push( new Color( 0, 1, 0 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.dynamic = true;\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( (object && object.isBone) ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar geometry = this.geometry;\n\n\t\tvar matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld );\n\n\t\tvar boneMatrix = new Matrix4();\n\n\t\tvar j = 0;\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\tgeometry.vertices[ j ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\tgeometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.verticesNeedUpdate = true;\n\n\t\tgeometry.computeBoundingSphere();\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction HemisphereLightHelper( light, sphereSize ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.colors = [ new Color(), new Color() ];\n\n\t\tvar geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tgeometry.rotateX( - Math.PI / 2 );\n\n\t\tfor ( var i = 0, il = 8; i < il; i ++ ) {\n\n\t\t\tgeometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];\n\n\t\t}\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } );\n\n\t\tthis.lightSphere = new Mesh( geometry, material );\n\t\tthis.add( this.lightSphere );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.lightSphere.geometry.dispose();\n\t\tthis.lightSphere.material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tthis.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tthis.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tthis.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\t\t\tthis.lightSphere.geometry.colorsNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tdivisions = divisions || 1;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = ( size * 2 ) / divisions;\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - size, 0, k, size, 0, k );\n\t\t\tvertices.push( k, 0, - size, k, 0, size );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new Geometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar hexFrustum = 0xffaa00;\n\t\tvar hexCone = 0xff0000;\n\t\tvar hexUp = 0x00aaff;\n\t\tvar hexTarget = 0xffffff;\n\t\tvar hexCross = 0x333333;\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", hexFrustum );\n\t\taddLine( \"n2\", \"n4\", hexFrustum );\n\t\taddLine( \"n4\", \"n3\", hexFrustum );\n\t\taddLine( \"n3\", \"n1\", hexFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", hexFrustum );\n\t\taddLine( \"f2\", \"f4\", hexFrustum );\n\t\taddLine( \"f4\", \"f3\", hexFrustum );\n\t\taddLine( \"f3\", \"f1\", hexFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", hexFrustum );\n\t\taddLine( \"n2\", \"f2\", hexFrustum );\n\t\taddLine( \"n3\", \"f3\", hexFrustum );\n\t\taddLine( \"n4\", \"f4\", hexFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", hexCone );\n\t\taddLine( \"p\", \"n2\", hexCone );\n\t\taddLine( \"p\", \"n3\", hexCone );\n\t\taddLine( \"p\", \"n4\", hexCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", hexUp );\n\t\taddLine( \"u2\", \"u3\", hexUp );\n\t\taddLine( \"u3\", \"u1\", hexUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", hexTarget );\n\t\taddLine( \"p\", \"c\", hexCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", hexCross );\n\t\taddLine( \"cn3\", \"cn4\", hexCross );\n\n\t\taddLine( \"cf1\", \"cf2\", hexCross );\n\t\taddLine( \"cf3\", \"cf4\", hexCross );\n\n\t\tfunction addLine( a, b, hex ) {\n\n\t\t\taddPoint( a, hex );\n\t\t\taddPoint( b, hex );\n\n\t\t}\n\n\t\tfunction addPoint( id, hex ) {\n\n\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\tgeometry.colors.push( new Color( hex ) );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( geometry.vertices.length - 1 );\n\n\t\t}\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tgeometry.vertices[ points[ i ] ].copy( vector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.verticesNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\t// a helper to show the world-axis-aligned bounding box for an object\n\n\tfunction BoundingBoxHelper( object, hex ) {\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0x888888;\n\n\t\tthis.object = object;\n\n\t\tthis.box = new Box3();\n\n\t\tMesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) );\n\n\t}\n\n\tBoundingBoxHelper.prototype = Object.create( Mesh.prototype );\n\tBoundingBoxHelper.prototype.constructor = BoundingBoxHelper;\n\n\tBoundingBoxHelper.prototype.update = function () {\n\n\t\tthis.box.setFromObject( this.object );\n\n\t\tthis.box.getSize( this.scale );\n\n\t\tthis.box.getCenter( this.position );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar 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 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( (object && object.isBox3) ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry = new BufferGeometry();\n\tlineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\tvar coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = new Float32Array( [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t] );\n\n\t\tvar colors = new Float32Array( [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t] );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\tvar CatmullRomCurve3 = ( function() {\n\n\t\tvar\n\t\t\ttmp = new Vector3(),\n\t\t\tpx = new CubicPoly(),\n\t\t\tpy = new CubicPoly(),\n\t\t\tpz = new CubicPoly();\n\n\t\t/*\n\t\tBased on an optimized c++ solution in\n\t\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t\t - http://ideone.com/NoEbVM\n\n\t\tThis CubicPoly class could be used for reusing some variables and calculations,\n\t\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\t\twhich can be placed in CurveUtils.\n\t\t*/\n\n\t\tfunction CubicPoly() {}\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tCubicPoly.prototype.init = function( x0, x1, t0, t1 ) {\n\n\t\t\tthis.c0 = x0;\n\t\t\tthis.c1 = t0;\n\t\t\tthis.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tthis.c3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t};\n\n\t\tCubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\t// initCubicPoly\n\t\t\tthis.init( x1, x2, t1, t2 );\n\n\t\t};\n\n\t\t// standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4\n\t\tCubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {\n\n\t\t\tthis.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t};\n\n\t\tCubicPoly.prototype.calc = function( t ) {\n\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t2 * t;\n\t\t\treturn this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;\n\n\t\t};\n\n\t\t// Subclass Three.js curve\n\t\treturn Curve.create(\n\n\t\t\tfunction ( p /* array of Vector3 */ ) {\n\n\t\t\t\tthis.points = p || [];\n\t\t\t\tthis.closed = false;\n\n\t\t\t},\n\n\t\t\tfunction ( t ) {\n\n\t\t\t\tvar points = this.points,\n\t\t\t\t\tpoint, intPoint, weight, l;\n\n\t\t\t\tl = points.length;\n\n\t\t\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\t\t\tpoint = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\t\t\tintPoint = Math.floor( point );\n\t\t\t\tweight = point - intPoint;\n\n\t\t\t\tif ( this.closed ) {\n\n\t\t\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\t\t\tintPoint = l - 2;\n\t\t\t\t\tweight = 1;\n\n\t\t\t\t}\n\n\t\t\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\t\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate first point\n\t\t\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\t\t\tp0 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tp1 = points[ intPoint % l ];\n\t\t\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\t\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate last point\n\t\t\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\t\t\tp3 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t\t\t// safety check for repeated points\n\t\t\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t\t\t}\n\n\t\t\t\tvar v = new Vector3(\n\t\t\t\t\tpx.calc( weight ),\n\t\t\t\t\tpy.calc( weight ),\n\t\t\t\t\tpz.calc( weight )\n\t\t\t\t);\n\n\t\t\t\treturn v;\n\n\t\t\t}\n\n\t\t);\n\n\t} )();\n\n\t/**************************************************************\n\t *\tClosed Spline 3D curve\n\t **************************************************************/\n\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t/**************************************************************\n\t *\tSpline 3D curve\n\t **************************************************************/\n\n\n\tvar SplineCurve3 = Curve.create(\n\n\t\tfunction ( points /* array of Vector3 */ ) {\n\n\t\t\tconsole.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );\n\t\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar points = this.points;\n\t\t\tvar point = ( points.length - 1 ) * t;\n\n\t\t\tvar intPoint = Math.floor( point );\n\t\t\tvar weight = point - intPoint;\n\n\t\t\tvar point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];\n\t\t\tvar point1 = points[ intPoint ];\n\t\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\t\treturn new Vector3(\n\t\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight ),\n\t\t\t\tinterpolate( point0.z, point1.z, point2.z, point3.z, weight )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tCubic Bezier 3D curve\n\t **************************************************************/\n\n\tvar CubicBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2, v3 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\t\t\tthis.v3 = v3;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b3 = ShapeUtils.b3;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),\n\t\t\t\tb3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tQuadratic Bezier 3D curve\n\t **************************************************************/\n\n\tvar QuadraticBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b2 = ShapeUtils.b2;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y ),\n\t\t\t\tb2( t, this.v0.z, this.v1.z, this.v2.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tLine3D\n\t **************************************************************/\n\n\tvar LineCurve3 = Curve.create(\n\n\t\tfunction ( v1, v2 ) {\n\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tif ( t === 1 ) {\n\n\t\t\t\treturn this.v2.clone();\n\n\t\t\t}\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\t\tvector.multiplyScalar( t );\n\t\t\tvector.add( this.v1 );\n\n\t\t\treturn vector;\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tArc curve\n\t **************************************************************/\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4 ( a, b, c, d, normal, color, materialIndex ) {\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction PointCloud ( geometry, material ) {\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction ParticleSystem ( geometry, material ) {\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction PointCloudMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleBasicMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleSystemMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction Vertex ( x, y, z ) {\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\t}\n\n\t//\n\n\tfunction EdgesHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\tfunction WireframeHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Line3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix3.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\t\textractPosition: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\t\t},\n\t\tsetRotationFromQuaternion: function ( q ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );\n\t\t\treturn vector.applyProjection( this );\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t},\n\t\trotateAxis: function ( v ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\ttranslate: function ( v ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\t\t},\n\t\trotateX: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\t\t},\n\t\trotateY: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\t\t},\n\t\trotateZ: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\t\t},\n\t\trotateByAxis: function ( axis, angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.assign( Plane.prototype, {\n\t\tisIntersectionLine: function ( line ) {\n\t\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\t\treturn this.intersectsLine( line );\n\t\t}\n\t} );\n\n\tObject.assign( Quaternion.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\t\treturn vector.applyQuaternion( this );\n\t\t}\n\t} );\n\n\tObject.assign( Ray.prototype, {\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t}\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\t\textrude: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\t\t}\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\t\tsetEulerFromRotationMatrix: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Object3D.prototype, {\n\t\tgetChildByName: function ( name ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\t\t},\n\t\trenderDepth: function ( value ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\t\t}\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\t\teulerOrder: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\t\tobjects: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\t\tlength: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );\n\t\t\t\treturn this.array.length;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\t\taddIndex: function ( index ) {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\t\t\tif ( indexOffset !== undefined ) {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\t\t},\n\t\tclearDrawCalls: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\t\t},\n\t\tcomputeTangents: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\t\t},\n\t\tcomputeOffsets: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\t\twrapAround: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\t\tmetal: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\t\tderivatives: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tEventDispatcher.prototype = Object.assign( Object.create( {\n\n\t\t// Note: Extra base ensures these properties are not 'assign'ed.\n\n\t\tconstructor: EventDispatcher,\n\n\t\tapply: function ( target ) {\n\n\t\t\tconsole.warn( \"THREE.EventDispatcher: .apply is deprecated, \" +\n\t\t\t\t\t\"just inherit or Object.assign the prototype to mix-in.\" );\n\n\t\t\tObject.assign( target, this );\n\n\t\t}\n\n\t} ), EventDispatcher.prototype );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\t\tdynamic: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\t\tsupportsFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\t\t\treturn this.capabilities.vertexTextures;\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\t\t},\n\t\tinitMaterial: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\t\t},\n\t\taddPrePlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\t\t},\n\t\taddPostPlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\t\t},\n\t\tupdateShadowMap: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.enabled;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.cullFace;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\t\tcullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\t\twrapS: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Audio.prototype, {\n\t\tload: function ( file ) {\n\t\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' );\n\t\t\tvar scope = this;\n\t\t\tvar audioLoader = new AudioLoader();\n\t\t\taudioLoader.load( file, function ( buffer ) {\n\t\t\t\tscope.setBuffer( buffer );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\t} );\n\n\tObject.assign( AudioAnalyser.prototype, {\n\t\tgetData: function ( file ) {\n\t\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\t\treturn this.getFrequencyData();\n\t\t}\n\t} );\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector () {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function ( vector, camera ) {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer () {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.TextureIdCount = TextureIdCount;\n\texports.Texture = Texture;\n\texports.MaterialIdCount = MaterialIdCount;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.XHRLoader = XHRLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.getAudioContext = getAudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3DIdCount = Object3DIdCount;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Spline = Spline;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.ColorKeywords = ColorKeywords;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.ShapePath = ShapePath;\n\texports.Path = Path;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.CurveUtils = CurveUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.BlendingMode = BlendingMode;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.TextureMapping = TextureMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.TextureWrapping = TextureWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.TextureFilter = TextureFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MultiMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Sprite;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n\tObject.defineProperty( exports, 'AudioContext', {\n\t\tget: function () {\n\t\t\treturn exports.getAudioContext();\n\t\t}\n\t});\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 2\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/silver-3da470.bmp\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/silver.bmp\n// module id = 3\n// module chunks = 0","\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\nimport Stats from 'stats-js'\r\nimport DAT from 'dat-gui'\r\n\r\n// when the scene is done initializing, the function passed as `callback` will be executed\r\n// then, every frame, the function passed as `update` will be executed\r\nfunction init(callback, update) {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var gui = new DAT.GUI({autoPlace: false});\r\n\r\n\r\n var framework = {\r\n gui: gui,\r\n stats: stats\r\n };\r\n\r\n // run this function after the window loads\r\n window.addEventListener('load', function() {\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x020202, 0);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.target.set(0, 0, 0);\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n controls.addEventListener('change', function() {\r\n camera.hasMoved = true;\r\n });\r\n\r\n document.body.appendChild(renderer.domElement);\r\n\r\n // resize the canvas when the window changes\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n }, false);\r\n\r\n // assign THREE.js objects to the object we will return\r\n framework.scene = scene;\r\n framework.camera = camera;\r\n framework.renderer = renderer;\r\n\r\n // begin the animation loop\r\n (function tick() {\r\n stats.begin();\r\n update(framework); // perform any requested updates\r\n renderer.render(scene, camera); // render the scene\r\n stats.end();\r\n requestAnimationFrame(tick); // register to call this again when the browser renders a new frame\r\n })();\r\n\r\n // we will pass the scene, gui, renderer, camera, etc... to the callback function\r\n return callback(framework);\r\n });\r\n}\r\n\r\nexport default {\r\n init: init\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/framework.js","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 5\n// module chunks = 0","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 6\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n height: 1em;\\n border-radius: 1em;\\n background-color: #eee;\\n padding: 0 0.5em;\\n overflow: hidden;\\n}\\n\\n.slider-fg {\\n padding: 1px 0 2px 0;\\n background-color: #aaa;\\n height: 1em;\\n margin-left: -0.5em;\\n padding-right: 0.5em;\\n border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n display: inline-block;\\n border-radius: 1em;\\n background-color: #fff;\\n border: 1px solid #aaa;\\n content: '';\\n float: right;\\n margin-right: -1em;\\n margin-top: -1px;\\n height: 0.9em;\\n width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 7\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 8\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 9\n// module chunks = 0","/////////////////////////////////////\r\n// Marching cubes lookup tables\r\n/////////////////////////////////////\r\n\r\n// Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/\r\n// These tables are straight from Paul Bourke's page:\r\n// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/\r\n// who in turn got them from Cory Gene Bloyd.\r\n\r\nvar EDGE_TABLE = new Int32Array([\r\n 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,\r\n 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,\r\n 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,\r\n 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,\r\n 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,\r\n 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,\r\n 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,\r\n 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,\r\n 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c,\r\n 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,\r\n 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc,\r\n 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,\r\n 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c,\r\n 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,\r\n 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,\r\n 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,\r\n 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,\r\n 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,\r\n 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,\r\n 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,\r\n 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,\r\n 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,\r\n 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,\r\n 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460,\r\n 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,\r\n 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0,\r\n 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,\r\n 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230,\r\n 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,\r\n 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,\r\n 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,\r\n 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0\r\n])\r\n\r\nvar TRI_TABLE = new Int32Array([\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,\r\n 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,\r\n 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1,\r\n 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1,\r\n 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1,\r\n 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1,\r\n 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1,\r\n 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1,\r\n 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1,\r\n 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1,\r\n 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1,\r\n 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,\r\n 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,\r\n 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,\r\n 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,\r\n 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,\r\n 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,\r\n 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,\r\n 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,\r\n 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,\r\n 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,\r\n 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,\r\n 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,\r\n 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,\r\n 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,\r\n 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,\r\n 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,\r\n 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,\r\n 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,\r\n 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,\r\n 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,\r\n 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,\r\n 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,\r\n 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,\r\n 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1,\r\n 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1,\r\n 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1,\r\n 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1,\r\n 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1,\r\n 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1,\r\n 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1,\r\n 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1,\r\n 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1,\r\n 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1,\r\n 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1,\r\n 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1,\r\n 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1,\r\n 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1,\r\n 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1,\r\n 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1,\r\n 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1,\r\n 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1,\r\n 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1,\r\n 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1,\r\n 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1,\r\n 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1,\r\n 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1,\r\n 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1,\r\n 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1,\r\n 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1,\r\n 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1,\r\n 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1,\r\n 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1,\r\n 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1,\r\n 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1,\r\n 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1,\r\n 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1,\r\n 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1,\r\n 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1,\r\n 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1,\r\n 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1,\r\n 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1,\r\n 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1,\r\n 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1,\r\n 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1,\r\n 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1,\r\n 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1,\r\n 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1,\r\n 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1,\r\n 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1,\r\n 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1,\r\n 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1,\r\n 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1,\r\n 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1,\r\n 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1,\r\n 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1,\r\n 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1,\r\n 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1,\r\n 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1,\r\n 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1,\r\n 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1,\r\n 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1,\r\n 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 3, 8, -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, -1, -1\r\n]);\r\n\r\nexport default {\r\n EDGE_TABLE: EDGE_TABLE,\r\n TRI_TABLE: TRI_TABLE\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cube_LUT.js","const THREE = require('three');\r\nimport {silverTexture} from './textures'\r\n\r\nimport Metaball from './metaball.js';\r\nimport InspectPoint from './inspect_point.js'\r\nimport LUT from './marching_cube_LUT.js';\r\nvar VISUAL_DEBUG = true;\r\nvar episolon = 0.1;\r\nvar balls = [];\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null};\r\n\r\n// lava\r\nvar l_mat = {\r\n uniforms: {\r\n texture: {type: \"t\",value: null},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/lava-vert.glsl'),\r\n fragmentShader: require('./shaders/lava-frag.glsl')\r\n};\r\n\r\nconst LAVA_MAT = new THREE.ShaderMaterial(l_mat);\r\nconst LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 });\r\nconst LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 });\r\nconst WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );\r\n\r\n// This function samples a point from the metaball's density function\r\n// Implement a function that returns the value of the all metaballs influence to a given point.\r\n// Please follow the resources given in the write-up for details.\r\nfunction sample(point) {\r\n var isovalue = 0.0;\r\n for (var i = 0; i < balls.length; i ++) {\r\n var r = balls[i].radius;\r\n var d = point.distanceTo(balls[i].pos);\r\n //isovalue += (r * r / (d * d)) * balls[i].neg;\r\n isovalue += (r * r / (d * d));\r\n }\r\n return isovalue;\r\n}\r\n\r\nexport default class MarchingCubes {\r\n\r\n constructor(App) {\r\n this.init(App);\r\n }\r\n\r\n init(App) {\r\n this.isPaused = false;\r\n VISUAL_DEBUG = App.config.visualDebug;\r\n\r\n // Initializing member variables.\r\n // Additional variables are used for fast computation.\r\n this.origin = new THREE.Vector3(0);\r\n\r\n this.isolevel = App.config.isolevel;\r\n this.minRadius = App.config.minRadius;\r\n this.maxRadius = App.config.maxRadius;\r\n\r\n this.gridCellWidth = App.config.gridCellWidth;\r\n this.gridCellHeight = App.config.gridCellHeight;\r\n this.gridCellDepth = App.config.gridCellDepth;\r\n this.halfCellWidth = App.config.gridCellWidth / 2.0;\r\n this.halfCellHeight = App.config.gridCellHeight / 2.0;\r\n this.halfCellDepth = App.config.gridCellDepth / 2.0;\r\n this.gridWidth = App.config.gridWidth;\r\n this.gridHeight = App.config.gridHeight;\r\n this.gridDepth = App.config.gridDepth;\r\n\r\n this.res = App.config.gridRes;\r\n this.res2 = App.config.gridRes * App.config.gridRes;\r\n this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes;\r\n\r\n this.maxSpeedX = App.config.maxSpeedX;\r\n this.maxSpeedY = App.config.maxSpeedY;\r\n this.maxSpeedZ = App.config.maxSpeedZ;\r\n this.numMetaballs = App.config.numMetaballs;\r\n\r\n this.camera = App.camera;\r\n this.scene = App.scene;\r\n\r\n this.voxels = [];\r\n //this.labels = [];\r\n this.balls = balls;\r\n\r\n this.showSpheres = true;\r\n this.showGrid = true;\r\n\r\n silverTexture.then(function(texture) {\r\n l_mat.uniforms.texture.value = texture;\r\n });\r\n\r\n if (App.config.material) {\r\n this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d});\r\n } else {\r\n this.material = App.config.material;\r\n }\r\n\r\n this.setupCells();\r\n this.setupMetaballs();\r\n this.makeMesh();\r\n };\r\n\r\n // Convert from 1D index to 3D indices\r\n i1toi3(i1) {\r\n\r\n // [i % w, i % (h * w)) / w, i / (h * w)]\r\n\r\n // @note: ~~ is a fast substitute for Math.floor()\r\n return [\r\n i1 % this.res,\r\n ~~ ((i1 % this.res2) / this.res),\r\n ~~ (i1 / this.res2)\r\n ];\r\n };\r\n\r\n // Convert from 3D indices to 1 1D\r\n i3toi1(i3x, i3y, i3z) {\r\n\r\n // [x + y * w + z * w * h]\r\n\r\n return i3x + i3y * this.res + i3z * this.res2;\r\n };\r\n\r\n // Convert from 3D indices to 3D positions\r\n i3toPos(i3) {\r\n\r\n return new THREE.Vector3(\r\n i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth,\r\n i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight,\r\n i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth\r\n );\r\n };\r\n\r\n setupCells() {\r\n\r\n // Allocate voxels based on our grid resolution\r\n this.voxels = [];\r\n for (var i = 0; i < this.res3; i++) {\r\n var i3 = this.i1toi3(i);\r\n var {x, y, z} = this.i3toPos(i3);\r\n var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth);\r\n this.voxels.push(voxel);\r\n\r\n if (VISUAL_DEBUG) {\r\n this.scene.add(voxel.wireframe);\r\n this.scene.add(voxel.mesh);\r\n }\r\n }\r\n }\r\n\r\n setupMetaballs() {\r\n\r\n var x, y, z, vx, vy, vz, radius, pos, vel;\r\n var matLambertWhite = LAMBERT_WHITE;\r\n var maxRadiusTRippled = this.maxRadius * 3;\r\n var maxRadiusDoubled = this.maxRadius * 2;\r\n\r\n // Randomly generate metaballs with different sizes and velocities\r\n for (var i = 0; i < this.numMetaballs; i++) {\r\n x = this.gridWidth / 2;\r\n y = this.gridHeight / 2;\r\n z = this.gridDepth / 2;\r\n pos = new THREE.Vector3(3, 3, 3);\r\n\r\n vx = 0\r\n vy = (Math.random() * 2 - 1) * this.maxSpeedY;\r\n vz = 0\r\n vel = new THREE.Vector3(vx, vy, vz);\r\n\r\n radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius;\r\n var neg = 1;\r\n if (Math.random()>0.75) neg = -1;\r\n var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG);\r\n balls.push(ball);\r\n\r\n // if (VISUAL_DEBUG) {\r\n // this.scene.add(ball.mesh);\r\n // }\r\n }\r\n this.balls = balls;\r\n }\r\n\r\n update() {\r\n\r\n if (this.isPaused) {\r\n return;\r\n }\r\n\r\n // This should move the metaballs\r\n balls.forEach(function(ball) {\r\n ball.update();\r\n });\r\n this.balls = balls;\r\n\r\n for (var c = 0; c < this.res3; c++) { // every voxel\r\n\r\n // Sampling the center and vertex points\r\n this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos);\r\n for (var i = 0; i < 8; i ++) {\r\n this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos);\r\n }\r\n\r\n // Visualizing grid\r\n if (VISUAL_DEBUG && this.showGrid) {\r\n\r\n // Toggle voxels on or off\r\n if (this.voxels[c].center.isovalue > this.isolevel) {\r\n this.voxels[c].show();\r\n } else {\r\n this.voxels[c].hide();\r\n }\r\n this.voxels[c].center.updateLabel(this.camera);\r\n } else {\r\n this.voxels[c].center.clearLabel();\r\n }\r\n }\r\n\r\n this.updateMesh();\r\n }\r\n\r\n pause() {\r\n this.isPaused = true;\r\n }\r\n\r\n play() {\r\n this.isPaused = false;\r\n }\r\n\r\n show() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].show();\r\n }\r\n this.showGrid = true;\r\n };\r\n\r\n hide() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].hide();\r\n }\r\n this.showGrid = false;\r\n };\r\n\r\n makeMesh() {\r\n // @TODO\r\n var geo = new THREE.Geometry();\r\n this.mesh = new THREE.Mesh(geo, LAVA_MAT);\r\n this.mesh.geometry.dynamic = true;\r\n this.scene.add(this.mesh);\r\n }\r\n\r\n updateMesh() {\r\n // @TODO\r\n var vertices = [];\r\n var faces = [];\r\n var count = 0;\r\n for (var i = 0; i < this.res3; i ++) {\r\n var vox_count = 0;\r\n var vANDn = this.voxels[i].polygonize(this.isolevel);\r\n for (var j = 0; j < vANDn.vertPositions.length/3; j ++) {\r\n var normals = [];\r\n for (var k = 0; k < 3; k ++) {\r\n vertices.push(vANDn.vertPositions[vox_count]);\r\n normals.push(vANDn.vertNormals[vox_count]);\r\n vox_count++;\r\n count++;\r\n }\r\n faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals));\r\n }\r\n }\r\n this.mesh.geometry.vertices = vertices;\r\n //this.mesh.geometry.normals = normals;\r\n this.mesh.geometry.faces = faces;\r\n this.mesh.geometry.verticesNeedUpdate = true;\r\n this.mesh.geometry.normalsNeedUpdate = true;\r\n this.mesh.geometry.elementsNeedUpdate = true;\r\n this.mesh.geometry.computeFaceNormals();\r\n //console.log(this.mesh);\r\n }\r\n};\r\n\r\n// ------------------------------------------- //\r\n\r\nclass Voxel {\r\n\r\n constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.init(position, gridCellWidth, gridCellHeight, gridCellDepth);\r\n }\r\n\r\n init(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.pos = position;\r\n this.gridCellWidth = gridCellWidth;\r\n this.gridCellHeight = gridCellHeight;\r\n this.gridCellDepth = gridCellDepth;\r\n this.corners = [];\r\n\r\n if (VISUAL_DEBUG) {\r\n this.makeMesh();\r\n }\r\n\r\n this.makeInspectPoints();\r\n }\r\n\r\n makeMesh() {\r\n var halfGridCellWidth = this.gridCellWidth / 2.0;\r\n var halfGridCellHeight = this.gridCellHeight / 2.0;\r\n var halfGridCellDepth = this.gridCellDepth / 2.0;\r\n\r\n var positions = new Float32Array([\r\n // Front face\r\n halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n\r\n // Back face\r\n -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n ]);\r\n\r\n var indices = new Uint16Array([\r\n 0, 1, 2, 3,\r\n 4, 5, 6, 7,\r\n 0, 7, 7, 4,\r\n 4, 3, 3, 0,\r\n 1, 6, 6, 5,\r\n 5, 2, 2, 1\r\n ]);\r\n\r\n // Buffer geometry\r\n var geo = new THREE.BufferGeometry();\r\n geo.setIndex( new THREE.BufferAttribute( indices, 1 ) );\r\n geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\r\n\r\n // Wireframe line segments\r\n this.wireframe = new THREE.LineSegments( geo, WIREFRAME_MAT );\r\n this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n\r\n // Green cube\r\n geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth);\r\n this.mesh = new THREE.Mesh( geo, LAMBERT_GREEN );\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n\r\n makeInspectPoints() {\r\n var w = this.gridCellWidth / 2.0;\r\n var h = this.gridCellHeight / 2.0;\r\n var d = this.gridCellDepth / 2.0;\r\n var x = this.pos.x;\r\n var y = this.pos.y;\r\n var z = this.pos.z;\r\n var red = 0xff0000;\r\n\r\n // Center dot\r\n this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG);\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG));\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n if (this.wireframe) {\r\n this.wireframe.visible = true;\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n\r\n if (this.wireframe) {\r\n this.wireframe.visible = false;\r\n }\r\n\r\n if (this.center) {\r\n this.center.clearLabel();\r\n }\r\n }\r\n\r\n vertexLerp(isolevel, posA, posB) {\r\n var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue);\r\n var lerpPos = new THREE.Vector3();\r\n return lerpPos.lerpVectors(posA.pos, posB.pos, t);\r\n }\r\n\r\n // returns an array of points on the cube edges\r\n // null if no point exists for an edge\r\n edgePoints(edges, x) {\r\n var points = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]);\r\n if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]);\r\n if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]);\r\n if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]);\r\n if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]);\r\n if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]);\r\n if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]);\r\n if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]);\r\n if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]);\r\n if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]);\r\n if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]);\r\n if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]);\r\n return points;\r\n }\r\n\r\n getNormal(point) {\r\n var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z);\r\n var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z);\r\n var x = sample(x1) - sample(x0);\r\n var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z);\r\n var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z);\r\n var y = sample(y1) - sample(y0);\r\n var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon);\r\n var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon);\r\n var z = sample(z1) - sample(z0);\r\n var n = new THREE.Vector3(x,y,z);\r\n return n.normalize();\r\n }\r\n\r\n polygonize(isolevel) {\r\n\r\n var vertexList = [];\r\n var normalList = [];\r\n var faceList = [];\r\n\r\n // get corner vertices that are inside metaballs\r\n var corner = 1;\r\n var allVert = 0;\r\n for (var i = 0; i < 8; i ++) {\r\n if (this.corners[i].isovalue > isolevel) {\r\n allVert |= corner;\r\n }\r\n corner = corner << 1;\r\n }\r\n\r\n if (allVert != 0) {\r\n // get intersected edges\r\n var edges = LUT.EDGE_TABLE[allVert];\r\n\r\n // get 12 points\r\n var points = this.edgePoints(edges, isolevel);\r\n\r\n for (var j = 0; j < 16; j ++) {\r\n var tri = LUT.TRI_TABLE[allVert*16 + j];\r\n if (tri < 0) break;\r\n var vertex = points[tri];\r\n vertexList.push(vertex);\r\n normalList.push(this.getNormal(vertex));\r\n }\r\n }\r\n\r\n\r\n return {\r\n vertPositions: vertexList,\r\n vertNormals: normalList\r\n };\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cubes.js","const THREE = require('three')\r\n\r\nvar SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32);\r\nvar LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 });\r\n\r\nexport default class Metaball {\r\n constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug);\r\n }\r\n\r\n init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.gridWidth = gridWidth;\r\n this.gridHeight = gridHeight;\r\n this.gridDepth = gridDepth;\r\n this.pos = pos;\r\n this.vel = vel;\r\n this.neg = neg;\r\n this.radius = radius;\r\n this.radius2 = radius * radius;\r\n this.mesh = null;\r\n this.debug = visualDebug;\r\n // if (visualDebug) {\r\n // this.makeMesh();\r\n // }\r\n }\r\n\r\n makeMesh() {\r\n this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE);\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n this.mesh.scale.set(this.radius, this.radius, this.radius);\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n };\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n };\r\n\r\n update() {\r\n\r\n // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z);\r\n // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir);\r\n // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2));\r\n // if ((dist + 2*this.radius) > this.gridWidth \r\n // || (dist + 2*this.radius) > this.gridDepth) {\r\n // this.vel.add(disp);\r\n // }\r\n var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0;\r\n if (y) this.vel.y *= -1;\r\n \r\n var date = new Date();\r\n var velocity = new THREE.Vector3();\r\n velocity.copy(this.vel).multiplyScalar(3);\r\n this.pos.add(velocity);\r\n\r\n \r\n\r\n \r\n // if (x || y || z) {\r\n // this.vel.multiplyScalar(-1);\r\n // }\r\n if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/metaball.js","const THREE = require('three');\r\n\r\nconst POINT_MATERIAL = new THREE.PointsMaterial( { color: 0xee1111, size: 10, sizeAttenuation: true } );\r\n\r\nexport default class InspectPoint {\r\n\r\n constructor(pos, isovalue, visualDebug) {\r\n this.init(pos, isovalue, visualDebug);\r\n }\r\n\r\n init(pos, isovalue, visualDebug) {\r\n this.pos = pos;\r\n this.isovalue = isovalue;\r\n this.label = null;\r\n\r\n if (visualDebug) {\r\n this.makeLabel();\r\n }\r\n };\r\n\r\n // Create an HTML div for holding label\r\n makeLabel() {\r\n this.label = document.createElement('div');\r\n this.label.style.position = 'absolute';\r\n this.label.style.width = 100;\r\n this.label.style.height = 100;\r\n this.label.style.userSelect = 'none';\r\n this.label.style.cursor = 'default';\r\n this.label.style.fontSize = '0.3em';\r\n this.label.style.pointerEvents = 'none';\r\n document.body.appendChild(this.label); \r\n };\r\n\r\n updateLabel(camera) {\r\n if (this.label) {\r\n var screenPos = this.pos.clone().project(camera);\r\n screenPos.x = ( screenPos.x + 1 ) / 2 * window.innerWidth;;\r\n screenPos.y = - ( screenPos.y - 1 ) / 2 * window.innerHeight;;\r\n\r\n this.label.style.top = screenPos.y + 'px';\r\n this.label.style.left = screenPos.x + 'px';\r\n this.label.innerHTML = this.isovalue.toFixed(2);\r\n this.label.style.opacity = this.isovalue - 0.5; \r\n }\r\n };\r\n\r\n clearLabel() {\r\n if (this.label) {\r\n this.label.innerHTML = '';\r\n this.label.style.opacity = 0;\r\n }\r\n };\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/inspect_point.js","module.exports = \"\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normalMatrix * normal;\\r\\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\nuniform sampler2D texture;\\r\\nuniform vec3 u_ambient;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 ref = reflect(e_position, f_normal);\\r\\n\\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\\r\\n float x = f_normal.x/m + 0.5;\\r\\n float y = f_normal.y/m + 0.5;\\r\\n\\r\\n vec4 color = texture2D(texture, vec2(x,y));\\r\\n\\r\\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","'use strict';\n\nmodule.exports = function (THREE) {\n\n /**\n * @author mrdoob / http://mrdoob.com/\n */\n THREE.OBJLoader = function (manager) {\n\n this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;\n };\n\n THREE.OBJLoader.prototype = {\n\n constructor: THREE.OBJLoader,\n\n load: function load(url, onLoad, onProgress, onError) {\n\n var scope = this;\n\n var loader = new THREE.XHRLoader(scope.manager);\n loader.load(url, function (text) {\n\n onLoad(scope.parse(text));\n }, onProgress, onError);\n },\n\n parse: function parse(text) {\n\n console.time('OBJLoader');\n\n var object,\n objects = [];\n var geometry, material;\n\n function parseVertexIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3;\n }\n\n function parseNormalIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + normals.length / 3) * 3;\n }\n\n function parseUVIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2;\n }\n\n function addVertex(a, b, c) {\n\n geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]);\n }\n\n function addNormal(a, b, c) {\n\n geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]);\n }\n\n function addUV(a, b, c) {\n\n geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]);\n }\n\n function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\n var ia = parseVertexIndex(a);\n var ib = parseVertexIndex(b);\n var ic = parseVertexIndex(c);\n var id;\n\n if (d === undefined) {\n\n addVertex(ia, ib, ic);\n } else {\n\n id = parseVertexIndex(d);\n\n addVertex(ia, ib, id);\n addVertex(ib, ic, id);\n }\n\n if (ua !== undefined) {\n\n ia = parseUVIndex(ua);\n ib = parseUVIndex(ub);\n ic = parseUVIndex(uc);\n\n if (d === undefined) {\n\n addUV(ia, ib, ic);\n } else {\n\n id = parseUVIndex(ud);\n\n addUV(ia, ib, id);\n addUV(ib, ic, id);\n }\n }\n\n if (na !== undefined) {\n\n ia = parseNormalIndex(na);\n ib = parseNormalIndex(nb);\n ic = parseNormalIndex(nc);\n\n if (d === undefined) {\n\n addNormal(ia, ib, ic);\n } else {\n\n id = parseNormalIndex(nd);\n\n addNormal(ia, ib, id);\n addNormal(ib, ic, id);\n }\n }\n }\n\n // create mesh if no objects in text\n\n if (/^o /gm.test(text) === false) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: '',\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n }\n\n var vertices = [];\n var normals = [];\n var uvs = [];\n\n // v float float float\n\n var vertex_pattern = /v( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vn float float float\n\n var normal_pattern = /vn( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vt float float\n\n var uv_pattern = /vt( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // f vertex vertex vertex ...\n\n var face_pattern1 = /f( +-?\\d+)( +-?\\d+)( +-?\\d+)( +-?\\d+)?/;\n\n // f vertex/uv vertex/uv vertex/uv ...\n\n var face_pattern2 = /f( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...\n\n var face_pattern3 = /f( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex//normal vertex//normal vertex//normal ...\n\n var face_pattern4 = /f( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))?/;\n\n //\n\n var lines = text.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n\n var line = lines[i];\n line = line.trim();\n\n var result;\n\n if (line.length === 0 || line.charAt(0) === '#') {\n\n continue;\n } else if ((result = vertex_pattern.exec(line)) !== null) {\n\n // [\"v 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = normal_pattern.exec(line)) !== null) {\n\n // [\"vn 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = uv_pattern.exec(line)) !== null) {\n\n // [\"vt 0.1 0.2\", \"0.1\", \"0.2\"]\n\n uvs.push(parseFloat(result[1]), parseFloat(result[2]));\n } else if ((result = face_pattern1.exec(line)) !== null) {\n\n // [\"f 1 2 3\", \"1\", \"2\", \"3\", undefined]\n\n addFace(result[1], result[2], result[3], result[4]);\n } else if ((result = face_pattern2.exec(line)) !== null) {\n\n // [\"f 1/1 2/2 3/3\", \" 1/1\", \"1\", \"1\", \" 2/2\", \"2\", \"2\", \" 3/3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]);\n } else if ((result = face_pattern3.exec(line)) !== null) {\n\n // [\"f 1/1/1 2/2/2 3/3/3\", \" 1/1/1\", \"1\", \"1\", \"1\", \" 2/2/2\", \"2\", \"2\", \"2\", \" 3/3/3\", \"3\", \"3\", \"3\", undefined, undefined, undefined, undefined]\n\n addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]);\n } else if ((result = face_pattern4.exec(line)) !== null) {\n\n // [\"f 1//1 2//2 3//3\", \" 1//1\", \"1\", \"1\", \" 2//2\", \"2\", \"2\", \" 3//3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]);\n } else if (/^o /.test(line)) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: line.substring(2).trim(),\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n } else if (/^g /.test(line)) {\n\n // group\n\n } else if (/^usemtl /.test(line)) {\n\n // material\n\n material.name = line.substring(7).trim();\n } else if (/^mtllib /.test(line)) {\n\n // mtl file\n\n } else if (/^s /.test(line)) {\n\n // smooth shading\n\n } else {\n\n // console.log( \"THREE.OBJLoader: Unhandled line \" + line );\n\n }\n }\n\n var container = new THREE.Object3D();\n var l;\n\n for (i = 0, l = objects.length; i < l; i++) {\n\n object = objects[i];\n geometry = object.geometry;\n\n var buffergeometry = new THREE.BufferGeometry();\n\n buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3));\n\n if (geometry.normals.length > 0) {\n\n buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3));\n }\n\n if (geometry.uvs.length > 0) {\n\n buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2));\n }\n\n material = new THREE.MeshLambertMaterial({\n color: 0xff0000\n });\n material.name = object.material.name;\n\n var mesh = new THREE.Mesh(buffergeometry, material);\n mesh.name = object.name;\n\n container.add(mesh);\n }\n\n console.timeEnd('OBJLoader');\n\n return container;\n }\n\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-obj-loader/dist/index.js\n// module id = 17\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n e_position = cameraPosition;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-vert.glsl\n// module id = 18\n// module chunks = 0","module.exports = \"#define M_PI 3.1415926535897932384626433832795\\r\\n\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nfloat cosine(float a, float b, float c, float d, float t) {\\r\\n\\treturn a + b * cos(2.0 * M_PI * (c * t + d));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\\r\\n\\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\\r\\n\\r\\n gl_FragColor = vec4(d,d,d, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-frag.glsl\n// module id = 19\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-vert.glsl\n// module id = 20\n// module chunks = 0","module.exports = \"uniform vec3 u_lightPos;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\\r\\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\\r\\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-frag.glsl\n// module id = 21\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap ffceba391a39c929c245","webpack:///./src/main.js","webpack:///./src/textures.js","webpack:///./~/three/build/three.js","webpack:///./src/assets/silver.bmp","webpack:///./src/framework.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/three-orbit-controls/index.js","webpack:///./src/marching_cube_LUT.js","webpack:///./src/marching_cubes.js","webpack:///./src/metaball.js","webpack:///./src/inspect_point.js","webpack:///./src/shaders/lava-vert.glsl","webpack:///./src/shaders/lava-frag.glsl","webpack:///./index.html","webpack:///./~/three-obj-loader/dist/index.js","webpack:///./src/shaders/glass-vert.glsl","webpack:///./src/shaders/glass-frag.glsl","webpack:///./src/shaders/metal-vert.glsl","webpack:///./src/shaders/metal-frag.glsl","webpack:///./src/assets/glass.obj","webpack:///./src/assets/lamp.obj"],"names":["require","THREE","OBJLoader","DEFAULT_VISUAL_DEBUG","DEFAULT_ISO_LEVEL","DEFAULT_GRID_RES","DEFAULT_GRID_WIDTH","DEFAULT_GRID_HEIGHT","DEFAULT_GRID_DEPTH","DEFAULT_NUM_METABALLS","DEFAULT_MIN_RADIUS","DEFAULT_MAX_RADIUS","DEFAULT_MAX_SPEEDX","DEFAULT_MAX_SPEEDY","options","lightColor","lightIntensity","ambient","albedo","loaded","red","Color","green","glassGeo","lampGeo","g_mat","uniforms","u_albedo","type","value","u_ambient","u_lightCol","u_lightIntensity","vertexShader","fragmentShader","m_mat","GLASS_MAT","MeshLambertMaterial","color","emissive","transparent","opacity","METAL_MAT","MeshPhongMaterial","App","marchingCubes","undefined","config","visualDebug","isolevel","gridRes","gridWidth","gridHeight","gridDepth","gridCellWidth","gridCellHeight","gridCellDepth","numMetaballs","minRadius","maxRadius","maxSpeedX","maxSpeedY","maxSpeedZ","camera","scene","renderer","isPaused","onLoad","framework","gui","stats","setClearColor","objLoader","obj","load","children","geometry","glass","Mesh","translateX","translateZ","add","lamp","setupCamera","setupLights","setupScene","setupGUI","cosine","a","b","c","d","t","Math","cos","PI","onUpdate","date","Date","sec","getSeconds","r","g","set","update","position","lookAt","Vector3","directionalLight","DirectionalLight","setHSL","multiplyScalar","step","onChange","reset","init","silverTexture","Promise","resolve","reject","TextureLoader","texture","OrbitControls","callback","setMode","domElement","style","left","top","document","body","appendChild","GUI","window","addEventListener","Scene","PerspectiveCamera","innerWidth","innerHeight","WebGLRenderer","antialias","alpha","setPixelRatio","devicePixelRatio","setSize","controls","enableDamping","enableZoom","target","rotateSpeed","zoomSpeed","panSpeed","hasMoved","aspect","updateProjectionMatrix","tick","begin","render","end","requestAnimationFrame","EDGE_TABLE","Int32Array","TRI_TABLE","VISUAL_DEBUG","episolon","balls","l_mat","LAVA_MAT","ShaderMaterial","LAMBERT_WHITE","LAMBERT_GREEN","MeshBasicMaterial","WIREFRAME_MAT","LineBasicMaterial","linewidth","sample","point","isovalue","i","length","radius","distanceTo","pos","MarchingCubes","origin","halfCellWidth","halfCellHeight","halfCellDepth","res","res2","res3","voxels","showSpheres","showGrid","then","material","setupCells","setupMetaballs","makeMesh","remove","mesh","i1","i3x","i3y","i3z","i3","x","y","z","i1toi3","i3toPos","voxel","Voxel","push","wireframe","vx","vy","vz","vel","matLambertWhite","maxRadiusTRippled","maxRadiusDoubled","random","neg","ball","forEach","center","corners","show","hide","updateLabel","clearLabel","updateMesh","geo","Geometry","dynamic","vertices","faces","count","vox_count","vANDn","polygonize","j","vertPositions","normals","k","vertNormals","Face3","verticesNeedUpdate","normalsNeedUpdate","elementsNeedUpdate","computeFaceNormals","makeInspectPoints","halfGridCellWidth","halfGridCellHeight","halfGridCellDepth","positions","Float32Array","indices","Uint16Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","BoxBufferGeometry","w","h","visible","posA","posB","lerpPos","lerpVectors","edges","points","vertexLerp","x0","x1","y0","y1","z0","z1","n","normalize","vertexList","normalList","faceList","corner","allVert","edgePoints","tri","vertex","getNormal","SPHERE_GEO","SphereBufferGeometry","Metaball","radius2","debug","scale","velocity","copy","POINT_MATERIAL","PointsMaterial","size","sizeAttenuation","InspectPoint","label","makeLabel","createElement","width","height","userSelect","cursor","fontSize","pointerEvents","screenPos","clone","project","innerHTML","toFixed"],"mappings":"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;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,0BAA0B;;AAEhE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2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AEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;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A0B,0BAA0B,wBAAwB,8CAA8C,qCAAqC,wCAAwC,6BAA6B,8CAA8C,swBAAswB,wFAAwF,yGAAyG,0CAA0C,qnBAAqnB,yDAAyD,6IAA6I;;AAEvpE,wEAAuE,8CAA8C,gYAAgY,iTAAiT,+QAA+Q,gEAAgE;;AAErnC,2CAA0C,uBAAuB,sIAAsI,sGAAsG,sCAAsC;;AAEnV,0CAAyC,kJAAkJ,iDAAiD,kKAAkK;;AAE9Y,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,8KAA8K,wKAAwK,mCAAmC,gJAAgJ;;AAEtkB,2CAA0C,yKAAyK,+EAA+E,GAAG;;AAErS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AAC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;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;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;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA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BAAkB;;AAE/C;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAE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;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AA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ACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,+BAA8B,OAAO;;AAErC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,kBAAiB;AACjB,kBAAiB;AACjB,kBAAiB;;AAEjB,iBAAgB,OAAO;;AAEvB;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB;AACnB,oBAAmB;AACnB,oBAAmB;;AAEnB;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,OAAO;;AAExB,MAAK;;AAEL,kBAAiB,OAAO;;AAExB;;AAEA;;AAEA;;AAEA,wBAAuB;;AAEvB,sBAAqB,QAAQ;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,YAAW,yBAAyB;AACpC,gBAAe,uBAAuB;AACtC,gBAAe,uBAAuB;;AAEtC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;AAEA;;AAEA,8BAA6B,QAAQ;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAe;AACf,+CAA8C;;AAE9C,MAAK;;AAEL;AACA;AACA;;AAEA;AACA,4DAA2D;AAC3D,4DAA2D;AAC3D;AACA;;AAEA;AACA,sDAAqD;AACrD,4BAA2B;;AAE3B;AACA;AACA;;AAEA,wFAAuF;AACvF;;AAEA;AACA;AACA;;AAEA,wFAAuF;AACvF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,4BAA2B;AAC3B,4BAA2B;;AAE3B,QAAO;;AAEP,4BAA2B;AAC3B,4BAA2B;;AAE3B;AACA;;AAEA,4BAA2B;AAC3B,4BAA2B;;AAE3B,QAAO;;AAEP,4BAA2B;AAC3B,4BAA2B;;AAE3B;;AAEA,OAAM;;AAEN;AACA;;AAEA,4BAA2B;AAC3B,4BAA2B;;AAE3B,QAAO;;AAEP,4BAA2B;AAC3B,4BAA2B;;AAE3B;AACA;;AAEA,4BAA2B;AAC3B,4BAA2B;;AAE3B,QAAO;;AAEP,4BAA2B;AAC3B,4BAA2B;;AAE3B;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,kCAAiC,aAAa;AAC9C;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;;AAGA;;AAEA,kCAAiC;AACjC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA,qBAAoB,qBAAqB;;AAEzC,0BAAyB;AACzB;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;;AAEhD;AACA,sBAAqB,uBAAuB;;AAE5C,2BAA0B;AAC1B;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,uCAAsC,2BAA2B;;AAEjE;AACA;;AAEA;AACA,uBAAsB,uBAAuB;;AAE7C;;AAEA;AACA;AACA;;AAEA;AACA,yBAAwB,kBAAkB;;AAE1C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,oCAAmC;;AAEnC,oCAAmC;;AAEnC;AACA,mCAAkC;;AAElC;;AAEA;;AAEA,kBAAiB;;AAEjB;;;AAGA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,QAAQ;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,QAAQ;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,uEAAsE;AACtE;;AAEA;;AAEA,uCAAsC,QAAQ;;AAE9C;;AAEA,iBAAgB,OAAO;;AAEvB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB,QAAQ;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,0FAAyF;AACzF,4FAA2F;AAC3F;;AAEA,uFAAsF;;AAEtF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,yBAAwB;;AAExB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,oBAAmB;AACnB;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,QAAQ;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB;;AAEnB;;;AAGA;;AAEA;;AAEA,0BAAyB;;AAEzB,kCAAiC,QAAQ;;AAEzC;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;;AAGA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,4CAA2C;;AAE3C;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,8BAA6B;AAC7B;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA,+DAA8D,QAAQ;;AAEtE;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAiC,QAAQ;;AAEzC;;AAEA;;AAEA,0DAAyD,QAAQ;;AAEjE;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA,eAAc,mBAAmB;;AAEjC,8BAA6B,OAAO;;AAEpC;AACA;AACA;;AAEA;;AAEA,qCAAoC,QAAQ;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,QAAQ;;AAE1C;AACA;;AAEA,oCAAmC,QAAQ;;AAE3C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,UAAU;;AAExB;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,eAAc,YAAY;;AAE1B,gBAAe,UAAU;;AAEzB;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA,iBAAgB,oBAAoB;AACpC,+BAA8B,QAAQ;;AAEtC;AACA;AACA;;AAEA;;AAEA,qCAAoC,QAAQ;;AAE5C;AACA;;AAEA;;AAEA;;AAEA,mCAAkC,QAAQ;;AAE1C;AACA;;AAEA,oCAAmC,QAAQ;;AAE3C;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,mBAAkB;AAClB;;AAEA;;AAEA,iBAAgB,UAAU;;AAE1B;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,iBAAgB,UAAU;;AAE1B;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,iBAAgB,UAAU;;AAE1B;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,UAAU;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,mCAAkC,QAAQ;;AAE1C;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB,QAAQ;;AAExB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,mBAAkB,qBAAqB;;AAEvC;;AAEA;;AAEA,oBAAmB,oBAAoB;;AAEvC;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB,oBAAoB;;AAEtC,oBAAmB,mBAAmB;;AAEtC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,kBAAkB;;AAEhC,gBAAe,oBAAoB;;AAEnC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,eAAc,iBAAiB;;AAE/B;;AAEA,gBAAe,mBAAmB;;AAElC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;AACA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A;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAE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;AAEhD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0FAAyF,4CAA4C;AACrI;;AAEA;AACA;AACA,8FAA6F,4CAA4C;AACzI;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAE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AEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;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A;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB,gCAA+B;;AAE/B;AACA;AACA,qCAAoC;AACpC,mCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;;AAEzB;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;;AAEA;AACA,gBAAe;;AAEf;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA,sBAAqB;AACrB,qBAAoB;AACpB,mBAAkB;;AAElB,gBAAe;;AAEf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA,gDAA+C;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap ffceba391a39c929c245","require('file-loader?name=[name].[ext]!../index.html');\r\nimport {silverTexture} from './textures'\r\n//import {quote} from './quote'\r\n// Credit:\r\n// http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/\r\n// http://paulbourke.net/geometry/polygonise/\r\n\r\nconst THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much\r\nconst OBJLoader = require('three-obj-loader');\r\nOBJLoader(THREE)\r\n\r\nimport Framework from './framework'\r\nimport LUT from './marching_cube_LUT.js'\r\nimport MarchingCubes from './marching_cubes.js'\r\n\r\nconst DEFAULT_VISUAL_DEBUG = false;\r\nconst DEFAULT_ISO_LEVEL = 1.0;\r\nconst DEFAULT_GRID_RES = 30;\r\nconst DEFAULT_GRID_WIDTH = 6;\r\nconst DEFAULT_GRID_HEIGHT = 17;\r\nconst DEFAULT_GRID_DEPTH = 6;\r\nconst DEFAULT_NUM_METABALLS = 7;\r\nconst DEFAULT_MIN_RADIUS = 0.5;\r\nconst DEFAULT_MAX_RADIUS = 1;\r\nconst DEFAULT_MAX_SPEEDX = 0.005;\r\nconst DEFAULT_MAX_SPEEDY = 0.3;\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'};\r\nvar loaded = false;\r\nvar red = new THREE.Color(1.0,0.0,0.0);\r\nvar green = new THREE.Color(0.0,1.0,0.0);\r\nvar glassGeo;\r\nvar lampGeo;\r\n\r\n// glass, emissive, iridescent\r\nvar g_mat = {\r\n uniforms: {\r\n u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/glass-vert.glsl'),\r\n fragmentShader: require('./shaders/glass-frag.glsl')\r\n};\r\n\r\n// metal\r\nvar m_mat = {\r\n uniforms: {\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/metal-vert.glsl'),\r\n fragmentShader: require('./shaders/metal-frag.glsl')\r\n};\r\n\r\n//const GLASS_MAT = new THREE.ShaderMaterial(g_mat);\r\nvar GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3});\r\nvar METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111});\r\n\r\nvar App = {\r\n //\r\n marchingCubes: undefined,\r\n config: {\r\n // Global control of all visual debugging.\r\n // This can be set to false to disallow any memory allocation of visual debugging components.\r\n // **Note**: If your application experiences performance drop, disable this flag.\r\n visualDebug: DEFAULT_VISUAL_DEBUG,\r\n\r\n // The isolevel for marching cubes\r\n isolevel: DEFAULT_ISO_LEVEL,\r\n\r\n // Grid resolution in each dimension. If gridRes = 4, then we have a 4x4x4 grid\r\n gridRes: DEFAULT_GRID_RES,\r\n\r\n // Total width of grid\r\n gridWidth: DEFAULT_GRID_WIDTH,\r\n\r\n gridHeight: DEFAULT_GRID_HEIGHT,\r\n\r\n gridDepth: DEFAULT_GRID_DEPTH,\r\n\r\n // Width of each voxel\r\n // Ideally, we want the voxel to be small (higher resolution)\r\n gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES,\r\n gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES,\r\n gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES,\r\n\r\n // Number of metaballs\r\n numMetaballs: DEFAULT_NUM_METABALLS,\r\n\r\n // Minimum radius of a metaball\r\n minRadius: DEFAULT_MIN_RADIUS,\r\n\r\n // Maxium radius of a metaball\r\n maxRadius: DEFAULT_MAX_RADIUS,\r\n\r\n // Maximum speed of a metaball\r\n maxSpeedX: DEFAULT_MAX_SPEEDX,\r\n maxSpeedY: DEFAULT_MAX_SPEEDY,\r\n maxSpeedZ: DEFAULT_MAX_SPEEDX, \r\n },\r\n\r\n // Scene's framework objects\r\n camera: undefined,\r\n scene: undefined,\r\n renderer: undefined,\r\n\r\n // Play/pause control for the simulation\r\n isPaused: false,\r\n color: 0xffffff\r\n};\r\n\r\n// called after the scene loads\r\nfunction onLoad(framework) {\r\n\r\n var {scene, camera, renderer, gui, stats} = framework;\r\n App.scene = scene;\r\n App.camera = camera;\r\n App.renderer = renderer;\r\n\r\n renderer.setClearColor( 0x111111 );\r\n //scene.add(new THREE.AxisHelper(20));\r\n\r\n var objLoader = new THREE.OBJLoader();\r\n var obj = objLoader.load(require('./assets/glass.obj'), function(obj) {\r\n glassGeo = obj.children[0].geometry;\r\n var glass = new THREE.Mesh(glassGeo, GLASS_MAT);\r\n glass.translateX(-1.5);\r\n glass.translateZ(-1.5);\r\n App.scene.add(glass);\r\n loaded = true;\r\n });\r\n\r\n var obj = objLoader.load(require('./assets/lamp.obj'), function(obj) {\r\n lampGeo = obj.children[0].geometry;\r\n var lamp = new THREE.Mesh(lampGeo, METAL_MAT);\r\n lamp.translateX(-1.5);\r\n lamp.translateZ(-1.5);\r\n App.scene.add(lamp);\r\n });\r\n\r\n setupCamera(App.camera);\r\n setupLights(App.scene);\r\n setupScene(App.scene);\r\n setupGUI(gui);\r\n}\r\n\r\nfunction cosine(a,b,c,d,t) {\r\n return a + b * Math.cos(2.0 * Math.PI * (c * t + d));\r\n}\r\n\r\n// called on frame updates\r\nfunction onUpdate(framework) {\r\n if (loaded) {\r\n var date = new Date();\r\n var sec = date.getSeconds();\r\n var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0);\r\n var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0);\r\n var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); \r\n GLASS_MAT.emissive.set(new THREE.Color(r,g,b));\r\n }\r\n if (App.marchingCubes) {\r\n App.marchingCubes.update();\r\n }\r\n}\r\n\r\nfunction setupCamera(camera) {\r\n // set camera position\r\n camera.position.set(25, 10, 25);\r\n camera.lookAt(new THREE.Vector3(8,0,-5));\r\n}\r\n\r\nfunction setupLights(scene) {\r\n\r\n // Directional light\r\n var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );\r\n directionalLight.color.setHSL(0.1, 1, 0.95);\r\n directionalLight.position.set(1, 10, 2);\r\n directionalLight.position.multiplyScalar(10);\r\n\r\n scene.add(directionalLight);\r\n}\r\n\r\nfunction setupScene(scene) {\r\n App.marchingCubes = new MarchingCubes(App);\r\n}\r\n\r\nfunction setupGUI(gui) {\r\n\r\n // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage\r\n\r\n gui.add(App.config, 'numMetaballs', 1, 10).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'minRadius', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxRadius', 1, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxSpeedY', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'isolevel', 0, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'gridRes', 1, 40).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n\r\n}\r\n\r\n// when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate\r\nFramework.init(onLoad, onUpdate);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n// this file is just for convenience. it sets up loading the mario obj and texture\r\n\r\nconst THREE = require('three');\r\n\r\nexport var silverTexture = new Promise((resolve, reject) => {\r\n (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) {\r\n resolve(texture);\r\n })\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/textures.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*(\\S*)\\s*\\(/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tObject.assign( EventDispatcher.prototype, {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\tvar REVISION = '82';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar BlendingMode = {\n\t\tNoBlending: NoBlending,\n\t\tNormalBlending: NormalBlending,\n\t\tAdditiveBlending: AdditiveBlending,\n\t\tSubtractiveBlending: SubtractiveBlending,\n\t\tMultiplyBlending: MultiplyBlending,\n\t\tCustomBlending: CustomBlending\n\t};\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar TextureMapping = {\n\t\tUVMapping: UVMapping,\n\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t};\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar TextureWrapping = {\n\t\tRepeatWrapping: RepeatWrapping,\n\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t};\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar TextureFilter = {\n\t\tNearestFilter: NearestFilter,\n\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\tLinearFilter: LinearFilter,\n\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t};\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\trandom16: function () {\n\n\t\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\t\treturn Math.random();\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: TextureIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.sourceFile = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\tvar count = 0;\n\tfunction TextureIdCount() { return count++; }\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\t\t\tthis.w = attribute.array[ index + 3 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyProjection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 projection matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\t\t\tvar d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide\n\n\t\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;\n\t\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;\n\t\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix4( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeFrustum: function ( left, right, bottom, top, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakePerspective: function ( fov, aspect, near, far ) {\n\n\t\t\tvar ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 );\n\t\t\tvar ymin = - ymax;\n\t\t\tvar xmin = ymin * aspect;\n\t\t\tvar xmax = ymax * aspect;\n\n\t\t\treturn this.makeFrustum( xmin, xmax, ymin, ymax, near, far );\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\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}\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\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}\\n\";\n\n\tvar 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\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n float maxComponent = max( max( value.r, value.g ), value.b );\\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n M = ceil( M * 255.0 ) / 255.0;\\n return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float D = max( maxRange / maxRGB, 1.0 );\\n D = min( floor( D ) / 255.0, 1.0 );\\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n vec4 vResult;\\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n vResult.w = fract(Le);\\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n return 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 float Le = value.z * 255.0 + value.w;\\n vec3 Xp_Y_XYZp;\\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\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\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color = pointLight.color;\\n\\t\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\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_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\\t#include \\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\\t#include \\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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar 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};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\\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_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar 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\";\n\n\tvar 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}\\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_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\";\n\n\tvar 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 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\\t\\t\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n return 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 return ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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 boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n return 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 color *= toneMappingExposure;\\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n color = max( vec3( 0.0 ), color - 0.004 );\\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar 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\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\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\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\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\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse = vec3( 0.0 );\\n\\treflectedLight.directSpecular = vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse = diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular = vec3( 0.0 );\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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 \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\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 \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\n}\\n\";\n\n\tvar normal_vert = \"varying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvNormal = normalize( normalMatrix * normal );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( (value && value.isColor) ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular : { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity : { value: 1 }, // temporary\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\n\t\t\t\t{\n\t\t\t\t\tscale : { value: 1 },\n\t\t\t\t\tdashSize : { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: {\n\n\t\t\t\topacity : { value: 1.0 }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\n\t\t\t\tlightPos: { value: new Vector3() }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\tShaderLib.standard.uniforms,\n\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t point.y < this.min.y || point.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyProjection( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( (fog && fog.isFog) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( (fog && fog.isFogExp2) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: MaterialIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( (currentValue && currentValue.isColor) ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( (currentValue && currentValue.isVector3) && (newValue && newValue.isVector3) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( (this.color && this.color.isColor) ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();\n\t\t\tif ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\n\t\t\tif ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.bumpMap && this.bumpMap.isTexture) ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( (this.normalMap && this.normalMap.isTexture) ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( (this.displacementMap && this.displacementMap.isTexture) ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.envMap && this.envMap.isTexture) ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\tvar count$1 = 0;\n\tfunction MaterialIdCount() { return count$1++; }\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tthis.makeEmpty();\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tvar array, offset, stride;\n\n\t\t\t\t\t\t\t\tif ( (attribute && attribute.isInterleavedBufferAttribute) ) {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.data.array;\n\t\t\t\t\t\t\t\t\toffset = attribute.offset;\n\t\t\t\t\t\t\t\t\tstride = attribute.data.stride;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.array;\n\t\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\t\tstride = 3;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor ( var i = offset, il = array.length; i < il; i += stride ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromArray( array, i );\n\t\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\t\t point.y < this.min.y || point.y > this.max.y ||\n\t\t\t\t\t point.z < this.min.z || point.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&\n\t\t\t\t ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\t\t box.max.z < this.min.z || box.min.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// 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.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box = new Box3();\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix3( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( (matrix && matrix.isMatrix4) ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.clearColor( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( (light && light.isPointLight) ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( (shadow && shadow.isSpotLightShadow) ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( (material && material.isMultiMaterial) ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: Object3DIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function(){}; \n\t\tthis.onAfterRender = function(){};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype, {\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( (object && object.isObject3D) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\tvar count$2 = 0;\n\tfunction Object3DIdCount() { return count$2++; }\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int16Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint16Array( array ), itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int32Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float64Array( array ), itemSize );\n\n\t}\n\n\t// Deprecated\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [ [] ];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype, {\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( (geometry && geometry.isGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( (mesh && mesh.isMesh) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\tvar dupIndex = - 1;\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tdupIndex = n;\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [ [] ];\n\t\t\tthis.colors = [];\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( var i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( var i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( var k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tvar count$3 = 0;\n\tfunction GeometryIdCount() { return count$3++; }\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'DirectGeometry';\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tcomputeBoundingBox: Geometry.prototype.computeBoundingBox,\n\t\tcomputeBoundingSphere: Geometry.prototype.computeBoundingSphere,\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tthis.index = index;\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( (attribute && attribute.isBufferAttribute) === false && (attribute && attribute.isInterleavedBufferAttribute) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToVector3Array( position.array );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToVector3Array( normal.array );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isPoints) || (object && object.isLine) ) {\n\n\t\t\t\tvar positions = new Float32Attribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32Attribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32Attribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( (object && object.isMesh) ) {\n\n\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isMesh) ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32Attribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32Attribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar positions = this.attributes.position.array;\n\n\t\t\tif ( positions !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromArray( positions );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar positions = this.attributes.position;\n\n\t\t\t\tif ( positions ) {\n\n\t\t\t\t\tvar array = positions.array;\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromArray( array );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i += 3 ) {\n\n\t\t\t\t\t\tvector.fromArray( array, i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC,\n\n\t\t\t\tpA = new Vector3(),\n\t\t\t\tpB = new Vector3(),\n\t\t\t\tpC = new Vector3(),\n\n\t\t\t\tcb = new Vector3(),\n\t\t\t\tab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( (geometry && geometry.isBufferGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {\n\n\t\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\t\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\t\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar uvs, intersection;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( attributes.uv !== undefined ) {\n\n\t\t\t\t\t\tuvs = attributes.uv.array;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = indices[ i ];\n\t\t\t\t\t\t\tb = indices[ i + 1 ];\n\t\t\t\t\t\t\tc = indices[ i + 2 ];\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length; i < l; i += 9 ) {\n\n\t\t\t\t\t\t\ta = i / 3;\n\t\t\t\t\t\t\tb = a + 1;\n\t\t\t\t\t\t\tc = a + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = (material && material.isMultiMaterial);\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );\n\t\tvar indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\t\tvar numberOfVertices = 0;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount( w, h, d ) {\n\n\t\t\tvar vertices = 0;\n\n\t\t\t// calculate the amount of vertices for each side (plane)\n\t\t\tvertices += (w + 1) * (h + 1) * 2; // xy\n\t\t\tvertices += (w + 1) * (d + 1) * 2; // xz\n\t\t\tvertices += (d + 1) * (h + 1) * 2; // zy\n\n\t\t\treturn vertices;\n\n\t\t}\n\n\t\tfunction calculateIndexCount( w, h, d ) {\n\n\t\t\tvar index = 0;\n\n\t\t\t// calculate the amount of squares for each side\n\t\t\tindex += w * h * 2; // xy\n\t\t\tindex += w * d * 2; // xz\n\t\t\tindex += d * h * 2; // zy\n\n\t\t\treturn index * 6; // two triangles per square => six vertices per square\n\n\t\t}\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth\t= width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\t\t\t\t\tvertices[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\t\t\t\t\tnormals[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tnormals[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tnormals[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// uvs\n\t\t\t\t\tuvs[ uvBufferOffset ] = ix / gridX;\n\t\t\t\t\tuvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\t\tuvBufferOffset += 2;\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\t// indices\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tindexBufferOffset += 6;\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar vertices = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar normals = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar uvs = new Float32Array( gridX1 * gridY1 * 2 );\n\n\t\tvar offset = 0;\n\t\tvar offset2 = 0;\n\n\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices[ offset ] = x;\n\t\t\t\tvertices[ offset + 1 ] = - y;\n\n\t\t\t\tnormals[ offset + 2 ] = 1;\n\n\t\t\t\tuvs[ offset2 ] = ix / gridX;\n\t\t\t\tuvs[ offset2 + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\toffset += 3;\n\t\t\t\toffset2 += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\toffset = 0;\n\n\t\tvar indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );\n\n\t\tfor ( var iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( var ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices[ offset ] = a;\n\t\t\t\tindices[ offset + 1 ] = b;\n\t\t\t\tindices[ offset + 2 ] = d;\n\n\t\t\t\tindices[ offset + 3 ] = b;\n\t\t\t\tindices[ offset + 4 ] = c;\n\t\t\t\tindices[ offset + 5 ] = d;\n\n\t\t\t\toffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makeFrustum(\n\t\t\t\t\tleft, left + width, top - height, top, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( (position && position.isInterleavedBufferAttribute) ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( 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\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( (map && map.isTexture) ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( (map && map.isWebGLRenderTarget) ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\t\t\tvar position = attributes.position;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar edges = {};\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;\n\t\t\tvar attribute = new BufferAttribute( new TypeArray( indices ), 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true;\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true;\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( (renderTarget && renderTarget.isWebGLRenderTargetCube) ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = (texture && texture.isCompressedTexture);\n\t\t\t\t\tvar isDataTexture = (texture.image[ 0 ] && texture.image[ 0 ].isDataTexture);\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( (texture && texture.isDepthTexture) ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( (texture && texture.isDataTexture) ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( (texture && texture.isCompressedTexture) ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( (renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture) ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a ) {\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tclearColor( 0, 0, 0, 1 );\n\t\t\tclearDepth( 1 );\n\t\t\tclearStencil( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tgl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction clearColor( r, g, b, a ) {\n\n\t\t\tcolorBuffer.setClear( r, g, b, a );\n\n\t\t}\n\n\t\tfunction clearDepth( depth ) {\n\n\t\t\tdepthBuffer.setClear( depth );\n\n\t\t}\n\n\t\tfunction clearStencil( stencil ) {\n\n\t\t\tstencilBuffer.setClear( stencil );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tclearColor: clearColor,\n\t\t\tclearDepth: clearDepth,\n\t\t\tclearStencil: clearStencil,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t// internal state cache\n\n\t\t_currentProgram = null,\n\t\t_currentRenderTarget = null,\n\t\t_currentFramebuffer = null,\n\t\t_currentMaterialId = - 1,\n\t\t_currentGeometryProgram = '',\n\t\t_currentCamera = null,\n\n\t\t_currentScissor = new Vector4(),\n\t\t_currentScissorTest = null,\n\n\t\t_currentViewport = new Vector4(),\n\n\t\t//\n\n\t\t_usedTextureUnits = 0,\n\n\t\t//\n\n\t\t_clearColor = new Color( 0x000000 ),\n\t\t_clearAlpha = 0,\n\n\t\t_width = _canvas.width,\n\t\t_height = _canvas.height,\n\n\t\t_pixelRatio = 1,\n\n\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t_scissorTest = false,\n\n\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t// frustum\n\n\t\t_frustum = new Frustum(),\n\n\t\t// clipping\n\n\t\t_clipping = new WebGLClipping(),\n\t\t_clippingEnabled = false,\n\t\t_localClippingEnabled = false,\n\n\t\t_sphere = new Sphere(),\n\n\t\t// camera matrices cache\n\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_vector3 = new Vector3(),\n\n\t\t// light arrays cache\n\n\t\t_lights = {\n\n\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\tshadows: []\n\n\t\t},\n\n\t\t// info\n\n\t\t_infoRender = {\n\n\t\t\tcalls: 0,\n\t\t\tvertices: 0,\n\t\t\tfaces: 0,\n\t\t\tpoints: 0\n\n\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\t\tvar backgroundCamera2 = new PerspectiveCamera();\n\t\tvar backgroundPlaneMesh = new Mesh(\n\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t);\n\t\tvar backgroundBoxShader = ShaderLib[ 'cube' ];\n\t\tvar backgroundBoxMesh = new Mesh(\n\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\tnew ShaderMaterial( {\n\t\t\t\tuniforms: backgroundBoxShader.uniforms,\n\t\t\t\tvertexShader: backgroundBoxShader.vertexShader,\n\t\t\t\tfragmentShader: backgroundBoxShader.fragmentShader,\n\t\t\t\tside: BackSide,\n\t\t\t\tdepthTest: false,\n\t\t\t\tdepthWrite: false,\n\t\t\t\tfog: false\n\t\t\t} )\n\t\t);\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction glClearColor( r, g, b, a ) {\n\n\t\t\tif ( _premultipliedAlpha === true ) {\n\n\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t}\n\n\t\t\tstate.clearColor( r, g, b, a );\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t ! material.isMeshStandardMaterial &&\n\t\t\t\t material.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar type = _gl.FLOAT;\n\t\t\t\t\t\tvar array = geometryAttribute.array;\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\n\t\t\t\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.FLOAT;\n\n\t\t\t\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.BYTE;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_BYTE;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\t\t\t\t\t\tvar buffer = objects.getAttributeBuffer( geometryAttribute );\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tglClearColor( background.r, background.g, background.b, 1 );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tbackgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t ! material.isRawShaderMaterial ||\n\t\t\t material.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes || \n\t \t\t\t\t materialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isShaderMaterial ||\n\t\t\t\t material.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\tm_uniforms.opacity.value = material.opacity;\n\n\t\t\t\t}\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\tr = 0, g = 0, b = 0,\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\tdistance,\n\t\t\tshadowMap,\n\n\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\t p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone( skin ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t\tthis.skin = skin;\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.skin = source.skin;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone( this );\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( (this.geometry && this.geometry.isGeometry) ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.type = type !== undefined ? type : UnsignedShortType;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar numEdges = 0;\n\n\t\t\t// allocate maximal size\n\t\t\tvar edges = new Uint32Array( 6 * faces.length );\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\tvar vertex = vertices[ edges [ 2 * i + j ] ];\n\n\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\tcoords[ index + 0 ] = vertex.x;\n\t\t\t\t\tcoords[ index + 1 ] = vertex.y;\n\t\t\t\t\tcoords[ index + 2 ] = vertex.z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// Indexed BufferGeometry\n\n\t\t\t\tvar indices = geometry.index.array;\n\t\t\t\tvar vertices = geometry.attributes.position;\n\t\t\t\tvar groups = geometry.groups;\n\t\t\t\tvar numEdges = 0;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.length );\n\n\t\t\t\t}\n\n\t\t\t\t// allocate maximal size\n\t\t\t\tvar edges = new Uint32Array( 2 * indices.length );\n\n\t\t\t\tfor ( var o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tvar group = groups[ o ];\n\n\t\t\t\t\tvar start = group.start;\n\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices[ i + j ];\n\t\t\t\t\t\t\tedge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];\n\t\t\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\t\tvar index2 = edges[ 2 * i + j ];\n\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices.getX( index2 );\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices.getY( index2 );\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices.getZ( index2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tvar vertices = geometry.attributes.position.array;\n\t\t\t\tvar numEdges = vertices.length / 3;\n\t\t\t\tvar numTris = numEdges / 3;\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numTris; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\tvar index = 18 * i + 6 * j;\n\n\t\t\t\t\t\tvar index1 = 9 * i + 3 * j;\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices[ index1 ];\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices[ index1 + 1 ];\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices[ index1 + 2 ];\n\n\t\t\t\t\t\tvar index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tcoords[ index + 3 ] = vertices[ index2 ];\n\t\t\t\t\t\tcoords[ index + 4 ] = vertices[ index2 + 1 ];\n\t\t\t\t\t\tcoords[ index + 5 ] = vertices[ index2 + 2 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// generate vertices and uvs\n\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j, p;\n\t\tvar u, v;\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tv = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tu = j / slices;\n\n\t\t\t\tp = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tvar indices = [];\n\t\tvar a, b, c, d;\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\ta = i * sliceCount + j;\n\t\t\t\tb = i * sliceCount + j + 1;\n\t\t\t\tc = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\td = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', Float32Attribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0 ; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols ; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius,detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t *\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar i, j, index = 0, indexOffset = 0;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\tuv.y = j / radialSegments;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\n\t\t// helper variables\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices[ vertexBufferOffset ] = vertex.x;\n\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vertex.y;\n\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vertex.z;\n\n\t\t\t\t// this vector is used to calculate the normal\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\n\t\t\t\t// normal\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals[ vertexBufferOffset ] = normal.x;\n\t\t\t\tnormals[ vertexBufferOffset + 1 ] = normal.y;\n\t\t\t\tnormals[ vertexBufferOffset + 2 ] = normal.z;\n\n\t\t\t\t// uv\n\t\t\t\tuvs[ uvBufferOffset ] = i / tubularSegments;\n\t\t\t\tuvs[ uvBufferOffset + 1 ] = j / radialSegments;\n\n\t\t\t\t// update offsets\n\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\tuvBufferOffset += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t// face two\n\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t// update offset\n\t\t\t\tindexBufferOffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// 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.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t},\n\n\t\t// Bezier Curves formulas obtained from\n\t\t// http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n\t\t// Quad Bezier Functions\n\n\t\tb2: ( function () {\n\n\t\t\tfunction b2p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p1( t, p ) {\n\n\t\t\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p2( t, p ) {\n\n\t\t\t\treturn t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b2( t, p0, p1, p2 ) {\n\n\t\t\t\treturn b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\t// Cubic Bezier Functions\n\n\t\tb3: ( function () {\n\n\t\t\tfunction b3p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p1( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * k * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p2( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * t * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p3( t, p ) {\n\n\t\t\t\treturn t * t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b3( t, p0, p1, p2, p3 ) {\n\n\t\t\t\treturn b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( (font && font.isFont) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * based on THREE.SphereGeometry\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );\n\n\t\tvar positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\tvar index = 0, vertices = [], normal = new Vector3();\n\n\t\tfor ( var y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = y / heightSegments;\n\n\t\t\tfor ( var x = 0; x <= widthSegments; x ++ ) {\n\n\t\t\t\tvar u = x / widthSegments;\n\n\t\t\t\tvar px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvar py = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvar pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tnormal.set( px, py, pz ).normalize();\n\n\t\t\t\tpositions.setXYZ( index, px, py, pz );\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\tverticesRow.push( index );\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tvertices.push( verticesRow );\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var y = 0; y < heightSegments; y ++ ) {\n\n\t\t\tfor ( var x = 0; x < widthSegments; x ++ ) {\n\n\t\t\t\tvar v1 = vertices[ y ][ x + 1 ];\n\t\t\t\tvar v2 = vertices[ y ][ x ];\n\t\t\t\tvar v3 = vertices[ y + 1 ][ x ];\n\t\t\t\tvar v4 = vertices[ y + 1 ][ x + 1 ];\n\n\t\t\t\tif ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );\n\t\t\t\tif ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', positions );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 );\n\t\tvar indexCount = thetaSegments * phiSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// some helper variables\n\t\tvar index = 0, indexOffset = 0, segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\t// values are generate from the inside of the ring to the outside\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, 0, 1 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex++;\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\t // points - to create a closed torus, one must use a set of points\n\t // like so: [ a, b, c, d, a ], see first is the same as last.\n\t // segments - the number of circumference segments to create\n\t // phiStart - the starting radian\n\t // phiLength - the radian (0 to 2PI) range of the lathed section\n\t // 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( segments + 1 ) * points.length;\n\t\tvar indexCount = segments * points.length * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar index = 0, indexOffset = 0, base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t} // next row\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t *\n\t * Creates a one-sided polygonal geometry from a path shape. Similar to\n\t * ExtrudeGeometry.\n\t *\n\t * parameters = {\n\t *\n\t *\tcurveSegments: , // number of points on the curves. NOT USED AT THE MOMENT.\n\t *\n\t *\tmaterial: // material index for front and back faces\n\t *\tuvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ShapeGeometry( shapes, options ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( Array.isArray( shapes ) === false ) shapes = [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * Add an array of shapes to THREE.ShapeGeometry.\n\t */\n\tShapeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tfor ( var i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tthis.addShape( shapes[ i ], options );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.\n\t */\n\tShapeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tif ( options === undefined ) options = {};\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar material = options.material;\n\t\tvar uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;\n\n\t\t//\n\n\t\tvar i, l, hole;\n\n\t\tvar shapesOffset = this.vertices.length;\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe...\n\n\t\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\t\thole = holes[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( hole ) ) {\n\n\t\t\t\t\tholes[ i ] = hole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false;\n\n\t\t}\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t// Vertices\n\n\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\thole = holes[ i ];\n\t\t\tvertices = vertices.concat( hole );\n\n\t\t}\n\n\t\t//\n\n\t\tvar vert, vlen = vertices.length;\n\t\tvar face, flen = faces.length;\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = vertices[ i ];\n\n\t\t\tthis.vertices.push( new Vector3( vert.x, vert.y, 0 ) );\n\n\t\t}\n\n\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\tface = faces[ i ];\n\n\t\t\tvar a = face[ 0 ] + shapesOffset;\n\t\t\tvar b = face[ 1 ] + shapesOffset;\n\t\t\tvar c = face[ 2 ] + shapesOffset;\n\n\t\t\tthis.faces.push( new Face3( a, b, c, null, null, material ) );\n\t\t\tthis.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tvar geometry2;\n\n\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar vertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tvar key = edge.toString();\n\n\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\thash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\thash[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar coords = [];\n\n\t\tfor ( var key in hash ) {\n\n\t\t\tvar h = hash[ key ];\n\n\t\t\tif ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = vertices[ h.vert1 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t\tvertex = vertices[ h.vert2 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) );\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// used to calculate buffer length\n\n\t\tvar nbCap = 0;\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) nbCap ++;\n\t\t\tif ( radiusBottom > 0 ) nbCap ++;\n\n\t\t}\n\n\t\tvar vertexCount = calculateVertexCount();\n\t\tvar indexCount = calculateIndexCount();\n\n\t\t// buffers\n\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\n\t\tvar index = 0,\n\t\t indexOffset = 0,\n\t\t indexArray = [],\n\t\t halfHeight = height / 2;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount() {\n\n\t\t\tvar count = ( radialSegments + 1 ) * ( heightSegments + 1 );\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap );\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction calculateIndexCount() {\n\n\t\t\tvar count = radialSegments * heightSegments * 2 * 3;\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += radialSegments * nbCap * 3;\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\t\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\t\t\t\t\tindexRow.push( index );\n\n\t\t\t\t\t// increase index\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\tvar i1 = indexArray[ y ][ x ];\n\t\t\t\t\tvar i2 = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar i3 = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar i4 = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices.setX( indexOffset, i1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i3 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// update counters\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = 0.5;\n\t\t\t\tuv.y = 0.5;\n\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t}\n\n\t\t\t\t// update counters\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tvar vertices = segments + 2;\n\n\t\tvar positions = new Float32Array( vertices * 3 );\n\t\tvar normals = new Float32Array( vertices * 3 );\n\t\tvar uvs = new Float32Array( vertices * 2 );\n\n\t\t// center data is already zero, but need to set a few extras\n\t\tnormals[ 2 ] = 1.0;\n\t\tuvs[ 0 ] = 0.5;\n\t\tuvs[ 1 ] = 0.5;\n\n\t\tfor ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\tpositions[ i ] = radius * Math.cos( segment );\n\t\t\tpositions[ i + 1 ] = radius * Math.sin( segment );\n\n\t\t\tnormals[ i + 2 ] = 1; // normal z\n\n\t\t\tuvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;\n\t\t\tuvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry,\n\t\tBoxGeometry: BoxGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib[ \"lights\" ],\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = materials instanceof Array ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction XHRLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( XHRLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[1];\n\t\t\t\tvar isBase64 = !!dataUriRegexResult[2];\n\t\t\t\tvar data = dataUriRegexResult[3];\n\n\t\t\t\tdata = window.decodeURIComponent(data);\n\n\t\t\t\tif( isBase64 ) {\n\t\t\t\t\tdata = window.atob(data);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { \"type\" : mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tvar DataTextureLoader = BinaryTextureLoader;\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( BinaryTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\t\t\timage.onload = function () {\n\n\t\t\t\timage.onload = null;\n\n\t\t\t\tURL.revokeObjectURL( image.src );\n\n\t\t\t\tif ( onLoad ) onLoad( image );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t};\n\t\t\timage.onerror = onError;\n\n\t\t\tif ( url.indexOf( 'data:' ) === 0 ) {\n\n\t\t\t\timage.src = url;\n\n\t\t\t} else {\n\n\t\t\t\tvar loader = new XHRLoader();\n\t\t\t\tloader.setPath( this.path );\n\t\t\t\tloader.setResponseType( 'blob' );\n\t\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\t\tloader.load( url, function ( blob ) {\n\n\t\t\t\t\timage.src = URL.createObjectURL( blob );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( light ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true,\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function() {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function() {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function( timeOffset ) {\n\n\t\t\tif( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function( timeScale ) {\n\n\t\t\tif( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== -1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to , 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function() {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function() {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number',\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max(\n\t\t\t\t\t\tduration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0;\n\t\t\t\t\t\t\t\tm !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack(\n\t\t\t\t\t\t\t\t'.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader ( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tscope.parse( JSON.parse( text ), onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.SplineCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = 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\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\t// TODO: Transformation for Curves?\n\n\t/**************************************************************\n\t *\t3D Curves\n\t **************************************************************/\n\n\t// A Factory method for creating new curve subclasses\n\n\tCurve.create = function ( constructor, getPointFunc ) {\n\n\t\tconstructor.prototype = Object.create( Curve.prototype );\n\t\tconstructor.prototype.constructor = constructor;\n\t\tconstructor.prototype.getPoint = getPointFunc;\n\n\t\treturn constructor;\n\n\t};\n\n\t/**************************************************************\n\t *\tLine\n\t **************************************************************/\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**************************************************************\n\t *\tEllipse curve\n\t **************************************************************/\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar CurveUtils = {\n\n\t\ttangentQuadraticBezier: function ( t, p0, p1, p2 ) {\n\n\t\t\treturn 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );\n\n\t\t},\n\n\t\t// Puay Bing, thanks for helping with this derivative!\n\n\t\ttangentCubicBezier: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\treturn - 3 * p0 * ( 1 - t ) * ( 1 - t ) +\n\t\t\t\t3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +\n\t\t\t\t6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +\n\t\t\t\t3 * t * t * p3;\n\n\t\t},\n\n\t\ttangentSpline: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\t// To check if my formulas are correct\n\n\t\t\tvar h00 = 6 * t * t - 6 * t; \t// derived from 2t^3 − 3t^2 + 1\n\t\t\tvar h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t\n\t\t\tvar h01 = - 6 * t * t + 6 * t; \t// − 2t3 + 3t2\n\t\t\tvar h11 = 3 * t * t - 2 * t;\t// t3 − t2\n\n\t\t\treturn h00 + h10 + h01 + h11;\n\n\t\t},\n\n\t\t// Catmull-Rom\n\n\t\tinterpolate: function( p0, p1, p2, p3, t ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t * t2;\n\t\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t};\n\n\t/**************************************************************\n\t *\tSpline curve\n\t **************************************************************/\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\treturn new Vector2(\n\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight )\n\t\t);\n\n\t};\n\n\t/**************************************************************\n\t *\tCubic Bezier curve\n\t **************************************************************/\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b3 = ShapeUtils.b3;\n\n\t\treturn new Vector2(\n\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t);\n\n\t};\n\n\tCubicBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentCubicBezier = CurveUtils.tangentCubicBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\ttangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t).normalize();\n\n\t};\n\n\t/**************************************************************\n\t *\tQuadratic Bezier curve\n\t **************************************************************/\n\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b2 = ShapeUtils.b2;\n\n\t\treturn new Vector2(\n\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t);\n\n\t};\n\n\n\tQuadraticBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\ttangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t).normalize();\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t *\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\n\t// minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\tfunction ShapePath() {\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\t}\n\n\tShapePath.prototype = {\n\t\tmoveTo: function ( x, y ) {\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push(this.currentPath);\n\t\t\tthis.currentPath.moveTo( x, y );\n\t\t},\n\t\tlineTo: function ( x, y ) {\n\t\t\tthis.currentPath.lineTo( x, y );\n\t\t},\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\t\t},\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\t\t},\n\t\tsplineThru: function ( pts ) {\n\t\t\tthis.currentPath.splineThru( pts );\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar offset = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar ret = createPath( chars[ i ], scale, offset );\n\t\t\t\t\toffset += ret.offset;\n\n\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offset ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3;\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb2( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tb2( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb3( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tb3( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offset: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tfunction getAudioContext() {\n\n\t\tif ( context === undefined ) {\n\n\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn context;\n\n\t}\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = getAudioContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = getAudioContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\t\tthis.source = this.context.createBufferSource();\n\t\tthis.source.onended = this.onEnded.bind( this );\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.source.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.source.buffer;\n\t\t\tsource.loop = this.source.loop;\n\t\t\tsource.onended = this.source.onended;\n\t\t\tsource.start( 0, this.startTime );\n\t\t\tsource.playbackRate.value = this.playbackRate;\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.value = this.playbackRate;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.source.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.loop = value;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\t\t\tmixFunction = this._slerp;\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\n\t\t\t\tbufferType = Array,\t\tmixFunction = this._select;\t\tbreak;\n\n\t\t\tdefault:\t\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( (root && root.isAnimationObjectGroup) ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:\\w+[\\/:])*)(\\w+)?(?:\\.(\\w+)(?:\\[(.+)\\])?)?\\.(\\w+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tvar knownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis.loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype, {\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function() {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function() {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function() {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function() {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Spline from Tween.js, slightly optimized (and trashed)\n\t * http://sole.github.com/tween.js/examples/05_spline.html\n\t *\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Spline( points ) {\n\n\t\tthis.points = points;\n\n\t\tvar c = [], v3 = { x: 0, y: 0, z: 0 },\n\t\tpoint, intPoint, weight, w2, w3,\n\t\tpa, pb, pc, pd;\n\n\t\tthis.initFromArray = function ( a ) {\n\n\t\t\tthis.points = [];\n\n\t\t\tfor ( var i = 0; i < a.length; i ++ ) {\n\n\t\t\t\tthis.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getPoint = function ( k ) {\n\n\t\t\tpoint = ( this.points.length - 1 ) * k;\n\t\t\tintPoint = Math.floor( point );\n\t\t\tweight = point - intPoint;\n\n\t\t\tc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;\n\t\t\tc[ 1 ] = intPoint;\n\t\t\tc[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;\n\t\t\tc[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;\n\n\t\t\tpa = this.points[ c[ 0 ] ];\n\t\t\tpb = this.points[ c[ 1 ] ];\n\t\t\tpc = this.points[ c[ 2 ] ];\n\t\t\tpd = this.points[ c[ 3 ] ];\n\n\t\t\tw2 = weight * weight;\n\t\t\tw3 = weight * w2;\n\n\t\t\tv3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );\n\t\t\tv3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );\n\t\t\tv3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );\n\n\t\t\treturn v3;\n\n\t\t};\n\n\t\tthis.getControlPointsArray = function () {\n\n\t\t\tvar i, p, l = this.points.length,\n\t\t\t\tcoords = [];\n\n\t\t\tfor ( i = 0; i < l; i ++ ) {\n\n\t\t\t\tp = this.points[ i ];\n\t\t\t\tcoords[ i ] = [ p.x, p.y, p.z ];\n\n\t\t\t}\n\n\t\t\treturn coords;\n\n\t\t};\n\n\t\t// approximate length by summing linear segments\n\n\t\tthis.getLength = function ( nSubDivisions ) {\n\n\t\t\tvar i, index, nSamples, position,\n\t\t\t\tpoint = 0, intPoint = 0, oldIntPoint = 0,\n\t\t\t\toldPosition = new Vector3(),\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tchunkLengths = [],\n\t\t\t\ttotalLength = 0;\n\n\t\t\t// first point has 0 length\n\n\t\t\tchunkLengths[ 0 ] = 0;\n\n\t\t\tif ( ! nSubDivisions ) nSubDivisions = 100;\n\n\t\t\tnSamples = this.points.length * nSubDivisions;\n\n\t\t\toldPosition.copy( this.points[ 0 ] );\n\n\t\t\tfor ( i = 1; i < nSamples; i ++ ) {\n\n\t\t\t\tindex = i / nSamples;\n\n\t\t\t\tposition = this.getPoint( index );\n\t\t\t\ttmpVec.copy( position );\n\n\t\t\t\ttotalLength += tmpVec.distanceTo( oldPosition );\n\n\t\t\t\toldPosition.copy( position );\n\n\t\t\t\tpoint = ( this.points.length - 1 ) * index;\n\t\t\t\tintPoint = Math.floor( point );\n\n\t\t\t\tif ( intPoint !== oldIntPoint ) {\n\n\t\t\t\t\tchunkLengths[ intPoint ] = totalLength;\n\t\t\t\t\toldIntPoint = intPoint;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// last point ends with total length\n\n\t\t\tchunkLengths[ chunkLengths.length ] = totalLength;\n\n\t\t\treturn { chunks: chunkLengths, total: totalLength };\n\n\t\t};\n\n\t\tthis.reparametrizeByArcLength = function ( samplingCoef ) {\n\n\t\t\tvar i, j,\n\t\t\t\tindex, indexCurrent, indexNext,\n\t\t\t\trealDistance,\n\t\t\t\tsampling, position,\n\t\t\t\tnewpoints = [],\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tsl = this.getLength();\n\n\t\t\tnewpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );\n\n\t\t\tfor ( i = 1; i < this.points.length; i ++ ) {\n\n\t\t\t\t//tmpVec.copy( this.points[ i - 1 ] );\n\t\t\t\t//linearDistance = tmpVec.distanceTo( this.points[ i ] );\n\n\t\t\t\trealDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];\n\n\t\t\t\tsampling = Math.ceil( samplingCoef * realDistance / sl.total );\n\n\t\t\t\tindexCurrent = ( i - 1 ) / ( this.points.length - 1 );\n\t\t\t\tindexNext = i / ( this.points.length - 1 );\n\n\t\t\t\tfor ( j = 1; j < sampling - 1; j ++ ) {\n\n\t\t\t\t\tindex = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );\n\n\t\t\t\t\tposition = this.getPoint( index );\n\t\t\t\t\tnewpoints.push( tmpVec.copy( position ).clone() );\n\n\t\t\t\t}\n\n\t\t\t\tnewpoints.push( tmpVec.copy( this.points[ i ] ).clone() );\n\n\t\t\t}\n\n\t\t\tthis.points = newpoints;\n\n\t\t};\n\n\t\t// Catmull-Rom\n\n\t\tfunction interpolate( p0, p1, p2, p3, t, t2, t3 ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5,\n\t\t\t\tv1 = ( p3 - p1 ) * 0.5;\n\n\t\t\treturn ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new Geometry();\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.colors.push( new Color( 0, 0, 1 ) );\n\t\t\t\tgeometry.colors.push( new Color( 0, 1, 0 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.dynamic = true;\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( (object && object.isBone) ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar geometry = this.geometry;\n\n\t\tvar matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld );\n\n\t\tvar boneMatrix = new Matrix4();\n\n\t\tvar j = 0;\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\tgeometry.vertices[ j ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\tgeometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.verticesNeedUpdate = true;\n\n\t\tgeometry.computeBoundingSphere();\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction HemisphereLightHelper( light, sphereSize ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.colors = [ new Color(), new Color() ];\n\n\t\tvar geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tgeometry.rotateX( - Math.PI / 2 );\n\n\t\tfor ( var i = 0, il = 8; i < il; i ++ ) {\n\n\t\t\tgeometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];\n\n\t\t}\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } );\n\n\t\tthis.lightSphere = new Mesh( geometry, material );\n\t\tthis.add( this.lightSphere );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.lightSphere.geometry.dispose();\n\t\tthis.lightSphere.material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tthis.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tthis.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tthis.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\t\t\tthis.lightSphere.geometry.colorsNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tdivisions = divisions || 1;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = ( size * 2 ) / divisions;\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - size, 0, k, size, 0, k );\n\t\t\tvertices.push( k, 0, - size, k, 0, size );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new Geometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar hexFrustum = 0xffaa00;\n\t\tvar hexCone = 0xff0000;\n\t\tvar hexUp = 0x00aaff;\n\t\tvar hexTarget = 0xffffff;\n\t\tvar hexCross = 0x333333;\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", hexFrustum );\n\t\taddLine( \"n2\", \"n4\", hexFrustum );\n\t\taddLine( \"n4\", \"n3\", hexFrustum );\n\t\taddLine( \"n3\", \"n1\", hexFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", hexFrustum );\n\t\taddLine( \"f2\", \"f4\", hexFrustum );\n\t\taddLine( \"f4\", \"f3\", hexFrustum );\n\t\taddLine( \"f3\", \"f1\", hexFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", hexFrustum );\n\t\taddLine( \"n2\", \"f2\", hexFrustum );\n\t\taddLine( \"n3\", \"f3\", hexFrustum );\n\t\taddLine( \"n4\", \"f4\", hexFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", hexCone );\n\t\taddLine( \"p\", \"n2\", hexCone );\n\t\taddLine( \"p\", \"n3\", hexCone );\n\t\taddLine( \"p\", \"n4\", hexCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", hexUp );\n\t\taddLine( \"u2\", \"u3\", hexUp );\n\t\taddLine( \"u3\", \"u1\", hexUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", hexTarget );\n\t\taddLine( \"p\", \"c\", hexCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", hexCross );\n\t\taddLine( \"cn3\", \"cn4\", hexCross );\n\n\t\taddLine( \"cf1\", \"cf2\", hexCross );\n\t\taddLine( \"cf3\", \"cf4\", hexCross );\n\n\t\tfunction addLine( a, b, hex ) {\n\n\t\t\taddPoint( a, hex );\n\t\t\taddPoint( b, hex );\n\n\t\t}\n\n\t\tfunction addPoint( id, hex ) {\n\n\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\tgeometry.colors.push( new Color( hex ) );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( geometry.vertices.length - 1 );\n\n\t\t}\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tgeometry.vertices[ points[ i ] ].copy( vector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.verticesNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\t// a helper to show the world-axis-aligned bounding box for an object\n\n\tfunction BoundingBoxHelper( object, hex ) {\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0x888888;\n\n\t\tthis.object = object;\n\n\t\tthis.box = new Box3();\n\n\t\tMesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) );\n\n\t}\n\n\tBoundingBoxHelper.prototype = Object.create( Mesh.prototype );\n\tBoundingBoxHelper.prototype.constructor = BoundingBoxHelper;\n\n\tBoundingBoxHelper.prototype.update = function () {\n\n\t\tthis.box.setFromObject( this.object );\n\n\t\tthis.box.getSize( this.scale );\n\n\t\tthis.box.getCenter( this.position );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar 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 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( (object && object.isBox3) ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry = new BufferGeometry();\n\tlineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\tvar coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = new Float32Array( [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t] );\n\n\t\tvar colors = new Float32Array( [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t] );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\tvar CatmullRomCurve3 = ( function() {\n\n\t\tvar\n\t\t\ttmp = new Vector3(),\n\t\t\tpx = new CubicPoly(),\n\t\t\tpy = new CubicPoly(),\n\t\t\tpz = new CubicPoly();\n\n\t\t/*\n\t\tBased on an optimized c++ solution in\n\t\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t\t - http://ideone.com/NoEbVM\n\n\t\tThis CubicPoly class could be used for reusing some variables and calculations,\n\t\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\t\twhich can be placed in CurveUtils.\n\t\t*/\n\n\t\tfunction CubicPoly() {}\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tCubicPoly.prototype.init = function( x0, x1, t0, t1 ) {\n\n\t\t\tthis.c0 = x0;\n\t\t\tthis.c1 = t0;\n\t\t\tthis.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tthis.c3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t};\n\n\t\tCubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\t// initCubicPoly\n\t\t\tthis.init( x1, x2, t1, t2 );\n\n\t\t};\n\n\t\t// standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4\n\t\tCubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {\n\n\t\t\tthis.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t};\n\n\t\tCubicPoly.prototype.calc = function( t ) {\n\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t2 * t;\n\t\t\treturn this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;\n\n\t\t};\n\n\t\t// Subclass Three.js curve\n\t\treturn Curve.create(\n\n\t\t\tfunction ( p /* array of Vector3 */ ) {\n\n\t\t\t\tthis.points = p || [];\n\t\t\t\tthis.closed = false;\n\n\t\t\t},\n\n\t\t\tfunction ( t ) {\n\n\t\t\t\tvar points = this.points,\n\t\t\t\t\tpoint, intPoint, weight, l;\n\n\t\t\t\tl = points.length;\n\n\t\t\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\t\t\tpoint = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\t\t\tintPoint = Math.floor( point );\n\t\t\t\tweight = point - intPoint;\n\n\t\t\t\tif ( this.closed ) {\n\n\t\t\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\t\t\tintPoint = l - 2;\n\t\t\t\t\tweight = 1;\n\n\t\t\t\t}\n\n\t\t\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\t\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate first point\n\t\t\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\t\t\tp0 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tp1 = points[ intPoint % l ];\n\t\t\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\t\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate last point\n\t\t\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\t\t\tp3 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t\t\t// safety check for repeated points\n\t\t\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t\t\t}\n\n\t\t\t\tvar v = new Vector3(\n\t\t\t\t\tpx.calc( weight ),\n\t\t\t\t\tpy.calc( weight ),\n\t\t\t\t\tpz.calc( weight )\n\t\t\t\t);\n\n\t\t\t\treturn v;\n\n\t\t\t}\n\n\t\t);\n\n\t} )();\n\n\t/**************************************************************\n\t *\tClosed Spline 3D curve\n\t **************************************************************/\n\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t/**************************************************************\n\t *\tSpline 3D curve\n\t **************************************************************/\n\n\n\tvar SplineCurve3 = Curve.create(\n\n\t\tfunction ( points /* array of Vector3 */ ) {\n\n\t\t\tconsole.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );\n\t\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar points = this.points;\n\t\t\tvar point = ( points.length - 1 ) * t;\n\n\t\t\tvar intPoint = Math.floor( point );\n\t\t\tvar weight = point - intPoint;\n\n\t\t\tvar point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];\n\t\t\tvar point1 = points[ intPoint ];\n\t\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\t\treturn new Vector3(\n\t\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight ),\n\t\t\t\tinterpolate( point0.z, point1.z, point2.z, point3.z, weight )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tCubic Bezier 3D curve\n\t **************************************************************/\n\n\tvar CubicBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2, v3 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\t\t\tthis.v3 = v3;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b3 = ShapeUtils.b3;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),\n\t\t\t\tb3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tQuadratic Bezier 3D curve\n\t **************************************************************/\n\n\tvar QuadraticBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b2 = ShapeUtils.b2;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y ),\n\t\t\t\tb2( t, this.v0.z, this.v1.z, this.v2.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tLine3D\n\t **************************************************************/\n\n\tvar LineCurve3 = Curve.create(\n\n\t\tfunction ( v1, v2 ) {\n\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tif ( t === 1 ) {\n\n\t\t\t\treturn this.v2.clone();\n\n\t\t\t}\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\t\tvector.multiplyScalar( t );\n\t\t\tvector.add( this.v1 );\n\n\t\t\treturn vector;\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tArc curve\n\t **************************************************************/\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4 ( a, b, c, d, normal, color, materialIndex ) {\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction PointCloud ( geometry, material ) {\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction ParticleSystem ( geometry, material ) {\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction PointCloudMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleBasicMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleSystemMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction Vertex ( x, y, z ) {\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\t}\n\n\t//\n\n\tfunction EdgesHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\tfunction WireframeHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Line3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix3.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\t\textractPosition: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\t\t},\n\t\tsetRotationFromQuaternion: function ( q ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );\n\t\t\treturn vector.applyProjection( this );\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t},\n\t\trotateAxis: function ( v ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\ttranslate: function ( v ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\t\t},\n\t\trotateX: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\t\t},\n\t\trotateY: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\t\t},\n\t\trotateZ: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\t\t},\n\t\trotateByAxis: function ( axis, angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.assign( Plane.prototype, {\n\t\tisIntersectionLine: function ( line ) {\n\t\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\t\treturn this.intersectsLine( line );\n\t\t}\n\t} );\n\n\tObject.assign( Quaternion.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\t\treturn vector.applyQuaternion( this );\n\t\t}\n\t} );\n\n\tObject.assign( Ray.prototype, {\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t}\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\t\textrude: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\t\t}\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\t\tsetEulerFromRotationMatrix: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Object3D.prototype, {\n\t\tgetChildByName: function ( name ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\t\t},\n\t\trenderDepth: function ( value ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\t\t}\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\t\teulerOrder: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\t\tobjects: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\t\tlength: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );\n\t\t\t\treturn this.array.length;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\t\taddIndex: function ( index ) {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\t\t\tif ( indexOffset !== undefined ) {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\t\t},\n\t\tclearDrawCalls: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\t\t},\n\t\tcomputeTangents: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\t\t},\n\t\tcomputeOffsets: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\t\twrapAround: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\t\tmetal: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\t\tderivatives: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tEventDispatcher.prototype = Object.assign( Object.create( {\n\n\t\t// Note: Extra base ensures these properties are not 'assign'ed.\n\n\t\tconstructor: EventDispatcher,\n\n\t\tapply: function ( target ) {\n\n\t\t\tconsole.warn( \"THREE.EventDispatcher: .apply is deprecated, \" +\n\t\t\t\t\t\"just inherit or Object.assign the prototype to mix-in.\" );\n\n\t\t\tObject.assign( target, this );\n\n\t\t}\n\n\t} ), EventDispatcher.prototype );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\t\tdynamic: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\t\tsupportsFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\t\t\treturn this.capabilities.vertexTextures;\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\t\t},\n\t\tinitMaterial: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\t\t},\n\t\taddPrePlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\t\t},\n\t\taddPostPlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\t\t},\n\t\tupdateShadowMap: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.enabled;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.cullFace;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\t\tcullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\t\twrapS: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Audio.prototype, {\n\t\tload: function ( file ) {\n\t\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' );\n\t\t\tvar scope = this;\n\t\t\tvar audioLoader = new AudioLoader();\n\t\t\taudioLoader.load( file, function ( buffer ) {\n\t\t\t\tscope.setBuffer( buffer );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\t} );\n\n\tObject.assign( AudioAnalyser.prototype, {\n\t\tgetData: function ( file ) {\n\t\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\t\treturn this.getFrequencyData();\n\t\t}\n\t} );\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector () {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function ( vector, camera ) {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer () {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.TextureIdCount = TextureIdCount;\n\texports.Texture = Texture;\n\texports.MaterialIdCount = MaterialIdCount;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.XHRLoader = XHRLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.getAudioContext = getAudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3DIdCount = Object3DIdCount;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Spline = Spline;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.ColorKeywords = ColorKeywords;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.ShapePath = ShapePath;\n\texports.Path = Path;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.CurveUtils = CurveUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.BlendingMode = BlendingMode;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.TextureMapping = TextureMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.TextureWrapping = TextureWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.TextureFilter = TextureFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MultiMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Sprite;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n\tObject.defineProperty( exports, 'AudioContext', {\n\t\tget: function () {\n\t\t\treturn exports.getAudioContext();\n\t\t}\n\t});\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 2\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/silver-3da470.bmp\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/silver.bmp\n// module id = 3\n// module chunks = 0","\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\nimport Stats from 'stats-js'\r\nimport DAT from 'dat-gui'\r\n\r\n// when the scene is done initializing, the function passed as `callback` will be executed\r\n// then, every frame, the function passed as `update` will be executed\r\nfunction init(callback, update) {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var framework = {\r\n gui: gui,\r\n stats: stats\r\n };\r\n\r\n // run this function after the window loads\r\n window.addEventListener('load', function() {\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x020202, 0);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.target.set(0, 0, 0);\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n controls.addEventListener('change', function() {\r\n camera.hasMoved = true;\r\n });\r\n\r\n document.body.appendChild(renderer.domElement);\r\n\r\n // resize the canvas when the window changes\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n }, false);\r\n\r\n // assign THREE.js objects to the object we will return\r\n framework.scene = scene;\r\n framework.camera = camera;\r\n framework.renderer = renderer;\r\n\r\n // begin the animation loop\r\n (function tick() {\r\n stats.begin();\r\n update(framework); // perform any requested updates\r\n renderer.render(scene, camera); // render the scene\r\n stats.end();\r\n requestAnimationFrame(tick); // register to call this again when the browser renders a new frame\r\n })();\r\n\r\n // we will pass the scene, gui, renderer, camera, etc... to the callback function\r\n return callback(framework);\r\n });\r\n}\r\n\r\nexport default {\r\n init: init\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/framework.js","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 5\n// module chunks = 0","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 6\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n height: 1em;\\n border-radius: 1em;\\n background-color: #eee;\\n padding: 0 0.5em;\\n overflow: hidden;\\n}\\n\\n.slider-fg {\\n padding: 1px 0 2px 0;\\n background-color: #aaa;\\n height: 1em;\\n margin-left: -0.5em;\\n padding-right: 0.5em;\\n border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n display: inline-block;\\n border-radius: 1em;\\n background-color: #fff;\\n border: 1px solid #aaa;\\n content: '';\\n float: right;\\n margin-right: -1em;\\n margin-top: -1px;\\n height: 0.9em;\\n width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 7\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 8\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 9\n// module chunks = 0","/////////////////////////////////////\r\n// Marching cubes lookup tables\r\n/////////////////////////////////////\r\n\r\n// Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/\r\n// These tables are straight from Paul Bourke's page:\r\n// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/\r\n// who in turn got them from Cory Gene Bloyd.\r\n\r\nvar EDGE_TABLE = new Int32Array([\r\n 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,\r\n 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,\r\n 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,\r\n 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,\r\n 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,\r\n 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,\r\n 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,\r\n 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,\r\n 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c,\r\n 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,\r\n 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc,\r\n 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,\r\n 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c,\r\n 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,\r\n 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,\r\n 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,\r\n 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,\r\n 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,\r\n 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,\r\n 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,\r\n 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,\r\n 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,\r\n 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,\r\n 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460,\r\n 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,\r\n 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0,\r\n 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,\r\n 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230,\r\n 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,\r\n 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,\r\n 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,\r\n 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0\r\n])\r\n\r\nvar TRI_TABLE = new Int32Array([\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,\r\n 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,\r\n 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1,\r\n 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1,\r\n 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1,\r\n 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1,\r\n 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1,\r\n 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1,\r\n 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1,\r\n 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1,\r\n 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1,\r\n 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,\r\n 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,\r\n 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,\r\n 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,\r\n 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,\r\n 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,\r\n 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,\r\n 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,\r\n 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,\r\n 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,\r\n 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,\r\n 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,\r\n 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,\r\n 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,\r\n 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,\r\n 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,\r\n 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,\r\n 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,\r\n 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,\r\n 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,\r\n 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,\r\n 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,\r\n 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,\r\n 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1,\r\n 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1,\r\n 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1,\r\n 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1,\r\n 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1,\r\n 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1,\r\n 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1,\r\n 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1,\r\n 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1,\r\n 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1,\r\n 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1,\r\n 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1,\r\n 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1,\r\n 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1,\r\n 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1,\r\n 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1,\r\n 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1,\r\n 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1,\r\n 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1,\r\n 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1,\r\n 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1,\r\n 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1,\r\n 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1,\r\n 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1,\r\n 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1,\r\n 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1,\r\n 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1,\r\n 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1,\r\n 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1,\r\n 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1,\r\n 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1,\r\n 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1,\r\n 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1,\r\n 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1,\r\n 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1,\r\n 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1,\r\n 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1,\r\n 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1,\r\n 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1,\r\n 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1,\r\n 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1,\r\n 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1,\r\n 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1,\r\n 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1,\r\n 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1,\r\n 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1,\r\n 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1,\r\n 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1,\r\n 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1,\r\n 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1,\r\n 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1,\r\n 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1,\r\n 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1,\r\n 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1,\r\n 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1,\r\n 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1,\r\n 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1,\r\n 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1,\r\n 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 3, 8, -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, -1, -1\r\n]);\r\n\r\nexport default {\r\n EDGE_TABLE: EDGE_TABLE,\r\n TRI_TABLE: TRI_TABLE\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cube_LUT.js","const THREE = require('three');\r\nimport {silverTexture} from './textures'\r\n\r\nimport Metaball from './metaball.js';\r\nimport InspectPoint from './inspect_point.js'\r\nimport LUT from './marching_cube_LUT.js';\r\nvar VISUAL_DEBUG = true;\r\nvar episolon = 0.1;\r\nvar balls = [];\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null};\r\n\r\n// lava\r\nvar l_mat = {\r\n uniforms: {\r\n texture: {type: \"t\",value: null},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/lava-vert.glsl'),\r\n fragmentShader: require('./shaders/lava-frag.glsl')\r\n};\r\n\r\nconst LAVA_MAT = new THREE.ShaderMaterial(l_mat);\r\nconst LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 });\r\nconst LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 });\r\nconst WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );\r\n\r\n// This function samples a point from the metaball's density function\r\n// Implement a function that returns the value of the all metaballs influence to a given point.\r\n// Please follow the resources given in the write-up for details.\r\nfunction sample(point) {\r\n var isovalue = 0.0;\r\n for (var i = 0; i < balls.length; i ++) {\r\n var r = balls[i].radius;\r\n var d = point.distanceTo(balls[i].pos);\r\n //isovalue += (r * r / (d * d)) * balls[i].neg;\r\n isovalue += (r * r / (d * d));\r\n }\r\n return isovalue;\r\n}\r\n\r\nexport default class MarchingCubes {\r\n\r\n constructor(App) {\r\n this.init(App);\r\n }\r\n\r\n init(App) {\r\n this.isPaused = false;\r\n VISUAL_DEBUG = App.config.visualDebug;\r\n\r\n // Initializing member variables.\r\n // Additional variables are used for fast computation.\r\n this.origin = new THREE.Vector3(0);\r\n\r\n this.isolevel = App.config.isolevel;\r\n this.minRadius = App.config.minRadius;\r\n this.maxRadius = App.config.maxRadius;\r\n\r\n this.gridCellWidth = App.config.gridCellWidth;\r\n this.gridCellHeight = App.config.gridCellHeight;\r\n this.gridCellDepth = App.config.gridCellDepth;\r\n this.halfCellWidth = App.config.gridCellWidth / 2.0;\r\n this.halfCellHeight = App.config.gridCellHeight / 2.0;\r\n this.halfCellDepth = App.config.gridCellDepth / 2.0;\r\n this.gridWidth = App.config.gridWidth;\r\n this.gridHeight = App.config.gridHeight;\r\n this.gridDepth = App.config.gridDepth;\r\n\r\n this.res = App.config.gridRes;\r\n this.res2 = App.config.gridRes * App.config.gridRes;\r\n this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes;\r\n\r\n this.maxSpeedX = App.config.maxSpeedX;\r\n this.maxSpeedY = App.config.maxSpeedY;\r\n this.maxSpeedZ = App.config.maxSpeedZ;\r\n this.numMetaballs = App.config.numMetaballs;\r\n\r\n this.camera = App.camera;\r\n this.scene = App.scene;\r\n\r\n this.voxels = [];\r\n //this.labels = [];\r\n this.balls = balls;\r\n\r\n this.showSpheres = true;\r\n this.showGrid = true;\r\n\r\n silverTexture.then(function(texture) {\r\n l_mat.uniforms.texture.value = texture;\r\n });\r\n\r\n if (App.config.material) {\r\n this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d});\r\n } else {\r\n this.material = App.config.material;\r\n }\r\n\r\n this.setupCells();\r\n this.setupMetaballs();\r\n this.makeMesh();\r\n };\r\n\r\n reset() {\r\n \tthis.scene.remove(this.mesh);\r\n \tthis.balls = []; balls = [];\r\n };\r\n\r\n // Convert from 1D index to 3D indices\r\n i1toi3(i1) {\r\n\r\n // [i % w, i % (h * w)) / w, i / (h * w)]\r\n\r\n // @note: ~~ is a fast substitute for Math.floor()\r\n return [\r\n i1 % this.res,\r\n ~~ ((i1 % this.res2) / this.res),\r\n ~~ (i1 / this.res2)\r\n ];\r\n };\r\n\r\n // Convert from 3D indices to 1 1D\r\n i3toi1(i3x, i3y, i3z) {\r\n\r\n // [x + y * w + z * w * h]\r\n\r\n return i3x + i3y * this.res + i3z * this.res2;\r\n };\r\n\r\n // Convert from 3D indices to 3D positions\r\n i3toPos(i3) {\r\n\r\n return new THREE.Vector3(\r\n i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth,\r\n i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight,\r\n i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth\r\n );\r\n };\r\n\r\n setupCells() {\r\n\r\n // Allocate voxels based on our grid resolution\r\n this.voxels = [];\r\n for (var i = 0; i < this.res3; i++) {\r\n var i3 = this.i1toi3(i);\r\n var {x, y, z} = this.i3toPos(i3);\r\n var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth);\r\n this.voxels.push(voxel);\r\n\r\n if (VISUAL_DEBUG) {\r\n this.scene.add(voxel.wireframe);\r\n this.scene.add(voxel.mesh);\r\n }\r\n }\r\n }\r\n\r\n setupMetaballs() {\r\n\r\n var x, y, z, vx, vy, vz, radius, pos, vel;\r\n var matLambertWhite = LAMBERT_WHITE;\r\n var maxRadiusTRippled = this.maxRadius * 3;\r\n var maxRadiusDoubled = this.maxRadius * 2;\r\n\r\n // Randomly generate metaballs with different sizes and velocities\r\n for (var i = 0; i < this.numMetaballs; i++) {\r\n x = this.gridWidth / 2;\r\n y = this.gridHeight / 2;\r\n z = this.gridDepth / 2;\r\n pos = new THREE.Vector3(3, 3, 3);\r\n\r\n vx = 0\r\n vy = (Math.random() * 2 - 1) * this.maxSpeedY/10;\r\n vz = 0\r\n vel = new THREE.Vector3(vx, vy, vz);\r\n\r\n radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius;\r\n var neg = 1;\r\n if (Math.random()>0.75) neg = -1;\r\n var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG);\r\n balls.push(ball);\r\n\r\n // if (VISUAL_DEBUG) {\r\n // this.scene.add(ball.mesh);\r\n // }\r\n }\r\n this.balls = balls;\r\n }\r\n\r\n update() {\r\n\r\n if (this.isPaused) {\r\n return;\r\n }\r\n\r\n // This should move the metaballs\r\n balls.forEach(function(ball) {\r\n ball.update();\r\n });\r\n this.balls = balls;\r\n\r\n for (var c = 0; c < this.res3; c++) { // every voxel\r\n\r\n // Sampling the center and vertex points\r\n this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos);\r\n for (var i = 0; i < 8; i ++) {\r\n this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos);\r\n }\r\n\r\n // Visualizing grid\r\n if (VISUAL_DEBUG && this.showGrid) {\r\n\r\n // Toggle voxels on or off\r\n if (this.voxels[c].center.isovalue > this.isolevel) {\r\n this.voxels[c].show();\r\n } else {\r\n this.voxels[c].hide();\r\n }\r\n this.voxels[c].center.updateLabel(this.camera);\r\n } else {\r\n this.voxels[c].center.clearLabel();\r\n }\r\n }\r\n\r\n this.updateMesh();\r\n }\r\n\r\n pause() {\r\n this.isPaused = true;\r\n }\r\n\r\n play() {\r\n this.isPaused = false;\r\n }\r\n\r\n show() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].show();\r\n }\r\n this.showGrid = true;\r\n };\r\n\r\n hide() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].hide();\r\n }\r\n this.showGrid = false;\r\n };\r\n\r\n makeMesh() {\r\n // @TODO\r\n var geo = new THREE.Geometry();\r\n this.mesh = new THREE.Mesh(geo, LAVA_MAT);\r\n this.mesh.geometry.dynamic = true;\r\n this.scene.add(this.mesh);\r\n }\r\n\r\n updateMesh() {\r\n // @TODO\r\n var vertices = [];\r\n var faces = [];\r\n var count = 0;\r\n for (var i = 0; i < this.res3; i ++) {\r\n var vox_count = 0;\r\n var vANDn = this.voxels[i].polygonize(this.isolevel);\r\n for (var j = 0; j < vANDn.vertPositions.length/3; j ++) {\r\n var normals = [];\r\n for (var k = 0; k < 3; k ++) {\r\n vertices.push(vANDn.vertPositions[vox_count]);\r\n normals.push(vANDn.vertNormals[vox_count]);\r\n vox_count++;\r\n count++;\r\n }\r\n faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals));\r\n }\r\n }\r\n this.mesh.geometry.vertices = vertices;\r\n //this.mesh.geometry.normals = normals;\r\n this.mesh.geometry.faces = faces;\r\n this.mesh.geometry.verticesNeedUpdate = true;\r\n this.mesh.geometry.normalsNeedUpdate = true;\r\n this.mesh.geometry.elementsNeedUpdate = true;\r\n this.mesh.geometry.computeFaceNormals();\r\n //console.log(this.mesh);\r\n }\r\n};\r\n\r\n// ------------------------------------------- //\r\n\r\nclass Voxel {\r\n\r\n constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.init(position, gridCellWidth, gridCellHeight, gridCellDepth);\r\n }\r\n\r\n init(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.pos = position;\r\n this.gridCellWidth = gridCellWidth;\r\n this.gridCellHeight = gridCellHeight;\r\n this.gridCellDepth = gridCellDepth;\r\n this.corners = [];\r\n\r\n if (VISUAL_DEBUG) {\r\n this.makeMesh();\r\n }\r\n\r\n this.makeInspectPoints();\r\n }\r\n\r\n makeMesh() {\r\n var halfGridCellWidth = this.gridCellWidth / 2.0;\r\n var halfGridCellHeight = this.gridCellHeight / 2.0;\r\n var halfGridCellDepth = this.gridCellDepth / 2.0;\r\n\r\n var positions = new Float32Array([\r\n // Front face\r\n halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n\r\n // Back face\r\n -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n ]);\r\n\r\n var indices = new Uint16Array([\r\n 0, 1, 2, 3,\r\n 4, 5, 6, 7,\r\n 0, 7, 7, 4,\r\n 4, 3, 3, 0,\r\n 1, 6, 6, 5,\r\n 5, 2, 2, 1\r\n ]);\r\n\r\n // Buffer geometry\r\n var geo = new THREE.BufferGeometry();\r\n geo.setIndex( new THREE.BufferAttribute( indices, 1 ) );\r\n geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\r\n\r\n // Wireframe line segments\r\n this.wireframe = new THREE.LineSegments( geo, WIREFRAME_MAT );\r\n this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n\r\n // Green cube\r\n geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth);\r\n this.mesh = new THREE.Mesh( geo, LAMBERT_GREEN );\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n\r\n makeInspectPoints() {\r\n var w = this.gridCellWidth / 2.0;\r\n var h = this.gridCellHeight / 2.0;\r\n var d = this.gridCellDepth / 2.0;\r\n var x = this.pos.x;\r\n var y = this.pos.y;\r\n var z = this.pos.z;\r\n var red = 0xff0000;\r\n\r\n // Center dot\r\n this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG);\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG));\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n if (this.wireframe) {\r\n this.wireframe.visible = true;\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n\r\n if (this.wireframe) {\r\n this.wireframe.visible = false;\r\n }\r\n\r\n if (this.center) {\r\n this.center.clearLabel();\r\n }\r\n }\r\n\r\n vertexLerp(isolevel, posA, posB) {\r\n var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue);\r\n var lerpPos = new THREE.Vector3();\r\n return lerpPos.lerpVectors(posA.pos, posB.pos, t);\r\n }\r\n\r\n // returns an array of points on the cube edges\r\n // null if no point exists for an edge\r\n edgePoints(edges, x) {\r\n var points = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]);\r\n if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]);\r\n if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]);\r\n if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]);\r\n if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]);\r\n if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]);\r\n if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]);\r\n if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]);\r\n if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]);\r\n if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]);\r\n if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]);\r\n if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]);\r\n return points;\r\n }\r\n\r\n getNormal(point) {\r\n var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z);\r\n var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z);\r\n var x = sample(x1) - sample(x0);\r\n var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z);\r\n var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z);\r\n var y = sample(y1) - sample(y0);\r\n var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon);\r\n var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon);\r\n var z = sample(z1) - sample(z0);\r\n var n = new THREE.Vector3(x,y,z);\r\n return n.normalize();\r\n }\r\n\r\n polygonize(isolevel) {\r\n\r\n var vertexList = [];\r\n var normalList = [];\r\n var faceList = [];\r\n\r\n // get corner vertices that are inside metaballs\r\n var corner = 1;\r\n var allVert = 0;\r\n for (var i = 0; i < 8; i ++) {\r\n if (this.corners[i].isovalue > isolevel) {\r\n allVert |= corner;\r\n }\r\n corner = corner << 1;\r\n }\r\n\r\n if (allVert != 0) {\r\n // get intersected edges\r\n var edges = LUT.EDGE_TABLE[allVert];\r\n\r\n // get 12 points\r\n var points = this.edgePoints(edges, isolevel);\r\n\r\n for (var j = 0; j < 16; j ++) {\r\n var tri = LUT.TRI_TABLE[allVert*16 + j];\r\n if (tri < 0) break;\r\n var vertex = points[tri];\r\n vertexList.push(vertex);\r\n normalList.push(this.getNormal(vertex));\r\n }\r\n }\r\n\r\n\r\n return {\r\n vertPositions: vertexList,\r\n vertNormals: normalList\r\n };\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cubes.js","const THREE = require('three')\r\n\r\nvar SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32);\r\nvar LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 });\r\n\r\nexport default class Metaball {\r\n constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug);\r\n }\r\n\r\n init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.gridWidth = gridWidth;\r\n this.gridHeight = gridHeight;\r\n this.gridDepth = gridDepth;\r\n this.pos = pos;\r\n this.vel = vel;\r\n this.neg = neg;\r\n this.radius = radius;\r\n this.radius2 = radius * radius;\r\n this.mesh = null;\r\n this.debug = visualDebug;\r\n // if (visualDebug) {\r\n // this.makeMesh();\r\n // }\r\n }\r\n\r\n makeMesh() {\r\n this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE);\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n this.mesh.scale.set(this.radius, this.radius, this.radius);\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n };\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n };\r\n\r\n update() {\r\n\r\n // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z);\r\n // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir);\r\n // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2));\r\n // if ((dist + 2*this.radius) > this.gridWidth \r\n // || (dist + 2*this.radius) > this.gridDepth) {\r\n // this.vel.add(disp);\r\n // }\r\n var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0;\r\n if (y) this.vel.y *= -1;\r\n \r\n var date = new Date();\r\n var velocity = new THREE.Vector3();\r\n velocity.copy(this.vel).multiplyScalar(3);\r\n this.pos.add(velocity);\r\n\r\n \r\n\r\n \r\n // if (x || y || z) {\r\n // this.vel.multiplyScalar(-1);\r\n // }\r\n if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/metaball.js","const THREE = require('three');\r\n\r\nconst POINT_MATERIAL = new THREE.PointsMaterial( { color: 0xee1111, size: 10, sizeAttenuation: true } );\r\n\r\nexport default class InspectPoint {\r\n\r\n constructor(pos, isovalue, visualDebug) {\r\n this.init(pos, isovalue, visualDebug);\r\n }\r\n\r\n init(pos, isovalue, visualDebug) {\r\n this.pos = pos;\r\n this.isovalue = isovalue;\r\n this.label = null;\r\n\r\n if (visualDebug) {\r\n this.makeLabel();\r\n }\r\n };\r\n\r\n // Create an HTML div for holding label\r\n makeLabel() {\r\n this.label = document.createElement('div');\r\n this.label.style.position = 'absolute';\r\n this.label.style.width = 100;\r\n this.label.style.height = 100;\r\n this.label.style.userSelect = 'none';\r\n this.label.style.cursor = 'default';\r\n this.label.style.fontSize = '0.3em';\r\n this.label.style.pointerEvents = 'none';\r\n document.body.appendChild(this.label); \r\n };\r\n\r\n updateLabel(camera) {\r\n if (this.label) {\r\n var screenPos = this.pos.clone().project(camera);\r\n screenPos.x = ( screenPos.x + 1 ) / 2 * window.innerWidth;;\r\n screenPos.y = - ( screenPos.y - 1 ) / 2 * window.innerHeight;;\r\n\r\n this.label.style.top = screenPos.y + 'px';\r\n this.label.style.left = screenPos.x + 'px';\r\n this.label.innerHTML = this.isovalue.toFixed(2);\r\n this.label.style.opacity = this.isovalue - 0.5; \r\n }\r\n };\r\n\r\n clearLabel() {\r\n if (this.label) {\r\n this.label.innerHTML = '';\r\n this.label.style.opacity = 0;\r\n }\r\n };\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/inspect_point.js","module.exports = \"\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normalMatrix * normal;\\r\\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\nuniform sampler2D texture;\\r\\nuniform vec3 u_ambient;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 ref = reflect(e_position, f_normal);\\r\\n\\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\\r\\n float x = f_normal.x/m + 0.5;\\r\\n float y = f_normal.y/m + 0.5;\\r\\n\\r\\n vec4 color = texture2D(texture, vec2(x,y));\\r\\n\\r\\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","'use strict';\n\nmodule.exports = function (THREE) {\n\n /**\n * @author mrdoob / http://mrdoob.com/\n */\n THREE.OBJLoader = function (manager) {\n\n this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;\n };\n\n THREE.OBJLoader.prototype = {\n\n constructor: THREE.OBJLoader,\n\n load: function load(url, onLoad, onProgress, onError) {\n\n var scope = this;\n\n var loader = new THREE.XHRLoader(scope.manager);\n loader.load(url, function (text) {\n\n onLoad(scope.parse(text));\n }, onProgress, onError);\n },\n\n parse: function parse(text) {\n\n console.time('OBJLoader');\n\n var object,\n objects = [];\n var geometry, material;\n\n function parseVertexIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3;\n }\n\n function parseNormalIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + normals.length / 3) * 3;\n }\n\n function parseUVIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2;\n }\n\n function addVertex(a, b, c) {\n\n geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]);\n }\n\n function addNormal(a, b, c) {\n\n geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]);\n }\n\n function addUV(a, b, c) {\n\n geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]);\n }\n\n function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\n var ia = parseVertexIndex(a);\n var ib = parseVertexIndex(b);\n var ic = parseVertexIndex(c);\n var id;\n\n if (d === undefined) {\n\n addVertex(ia, ib, ic);\n } else {\n\n id = parseVertexIndex(d);\n\n addVertex(ia, ib, id);\n addVertex(ib, ic, id);\n }\n\n if (ua !== undefined) {\n\n ia = parseUVIndex(ua);\n ib = parseUVIndex(ub);\n ic = parseUVIndex(uc);\n\n if (d === undefined) {\n\n addUV(ia, ib, ic);\n } else {\n\n id = parseUVIndex(ud);\n\n addUV(ia, ib, id);\n addUV(ib, ic, id);\n }\n }\n\n if (na !== undefined) {\n\n ia = parseNormalIndex(na);\n ib = parseNormalIndex(nb);\n ic = parseNormalIndex(nc);\n\n if (d === undefined) {\n\n addNormal(ia, ib, ic);\n } else {\n\n id = parseNormalIndex(nd);\n\n addNormal(ia, ib, id);\n addNormal(ib, ic, id);\n }\n }\n }\n\n // create mesh if no objects in text\n\n if (/^o /gm.test(text) === false) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: '',\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n }\n\n var vertices = [];\n var normals = [];\n var uvs = [];\n\n // v float float float\n\n var vertex_pattern = /v( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vn float float float\n\n var normal_pattern = /vn( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vt float float\n\n var uv_pattern = /vt( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // f vertex vertex vertex ...\n\n var face_pattern1 = /f( +-?\\d+)( +-?\\d+)( +-?\\d+)( +-?\\d+)?/;\n\n // f vertex/uv vertex/uv vertex/uv ...\n\n var face_pattern2 = /f( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...\n\n var face_pattern3 = /f( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex//normal vertex//normal vertex//normal ...\n\n var face_pattern4 = /f( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))?/;\n\n //\n\n var lines = text.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n\n var line = lines[i];\n line = line.trim();\n\n var result;\n\n if (line.length === 0 || line.charAt(0) === '#') {\n\n continue;\n } else if ((result = vertex_pattern.exec(line)) !== null) {\n\n // [\"v 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = normal_pattern.exec(line)) !== null) {\n\n // [\"vn 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = uv_pattern.exec(line)) !== null) {\n\n // [\"vt 0.1 0.2\", \"0.1\", \"0.2\"]\n\n uvs.push(parseFloat(result[1]), parseFloat(result[2]));\n } else if ((result = face_pattern1.exec(line)) !== null) {\n\n // [\"f 1 2 3\", \"1\", \"2\", \"3\", undefined]\n\n addFace(result[1], result[2], result[3], result[4]);\n } else if ((result = face_pattern2.exec(line)) !== null) {\n\n // [\"f 1/1 2/2 3/3\", \" 1/1\", \"1\", \"1\", \" 2/2\", \"2\", \"2\", \" 3/3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]);\n } else if ((result = face_pattern3.exec(line)) !== null) {\n\n // [\"f 1/1/1 2/2/2 3/3/3\", \" 1/1/1\", \"1\", \"1\", \"1\", \" 2/2/2\", \"2\", \"2\", \"2\", \" 3/3/3\", \"3\", \"3\", \"3\", undefined, undefined, undefined, undefined]\n\n addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]);\n } else if ((result = face_pattern4.exec(line)) !== null) {\n\n // [\"f 1//1 2//2 3//3\", \" 1//1\", \"1\", \"1\", \" 2//2\", \"2\", \"2\", \" 3//3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]);\n } else if (/^o /.test(line)) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: line.substring(2).trim(),\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n } else if (/^g /.test(line)) {\n\n // group\n\n } else if (/^usemtl /.test(line)) {\n\n // material\n\n material.name = line.substring(7).trim();\n } else if (/^mtllib /.test(line)) {\n\n // mtl file\n\n } else if (/^s /.test(line)) {\n\n // smooth shading\n\n } else {\n\n // console.log( \"THREE.OBJLoader: Unhandled line \" + line );\n\n }\n }\n\n var container = new THREE.Object3D();\n var l;\n\n for (i = 0, l = objects.length; i < l; i++) {\n\n object = objects[i];\n geometry = object.geometry;\n\n var buffergeometry = new THREE.BufferGeometry();\n\n buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3));\n\n if (geometry.normals.length > 0) {\n\n buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3));\n }\n\n if (geometry.uvs.length > 0) {\n\n buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2));\n }\n\n material = new THREE.MeshLambertMaterial({\n color: 0xff0000\n });\n material.name = object.material.name;\n\n var mesh = new THREE.Mesh(buffergeometry, material);\n mesh.name = object.name;\n\n container.add(mesh);\n }\n\n console.timeEnd('OBJLoader');\n\n return container;\n }\n\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-obj-loader/dist/index.js\n// module id = 17\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n e_position = cameraPosition;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-vert.glsl\n// module id = 18\n// module chunks = 0","module.exports = \"#define M_PI 3.1415926535897932384626433832795\\r\\n\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nfloat cosine(float a, float b, float c, float d, float t) {\\r\\n\\treturn a + b * cos(2.0 * M_PI * (c * t + d));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\\r\\n\\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\\r\\n\\r\\n gl_FragColor = vec4(d,d,d, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-frag.glsl\n// module id = 19\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-vert.glsl\n// module id = 20\n// module chunks = 0","module.exports = \"uniform vec3 u_lightPos;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\\r\\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\\r\\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-frag.glsl\n// module id = 21\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/glass-5b14a7.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/glass.obj\n// module id = 22\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/lamp-1bcc16.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/lamp.obj\n// module id = 23\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/src/assets/glass.obj b/src/assets/glass.obj new file mode 100644 index 0000000..11a96f9 --- /dev/null +++ b/src/assets/glass.obj @@ -0,0 +1,4423 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib glass.mtl +g default +v 1.034828 0.023645 5.000000 +v 2.478410 15.929955 5.000000 +v 7.521590 15.929955 5.000000 +v 8.965172 0.023645 5.000000 +v 1.417236 7.928881 5.000000 +v 8.582764 7.928881 5.000000 +v 3.208639 7.928881 1.897309 +v 3.017437 0.023645 1.566141 +v 0.875664 2.621381 5.000000 +v 2.937856 2.621381 1.428304 +v 1.428295 2.621381 2.937872 +v 1.566132 0.023645 3.017453 +v 0.821208 0.615620 5.000000 +v 1.381136 0.615620 2.910645 +v 0.963631 0.615620 3.918452 +v 1.169970 0.023645 3.973740 +v 0.894509 0.142910 5.000000 +v 1.034433 0.142910 3.937423 +v 0.929731 0.142910 4.464145 +v 1.068846 0.023645 4.482460 +v 0.956291 0.039097 5.000000 +v 0.990983 0.039097 4.472209 +v 0.964993 0.039097 4.735543 +v 1.043362 0.023645 4.740679 +v 0.993465 0.020326 5.000000 +v 1.002088 0.020326 4.737974 +v 1.027838 0.020326 4.477061 +v 1.094110 0.039097 3.953414 +v 1.111107 0.023645 4.226447 +v 1.034081 0.039097 4.211125 +v 1.070540 0.020326 4.218377 +v 1.130017 0.020326 3.963035 +v 1.444614 0.142910 2.947294 +v 1.336707 0.023645 3.482630 +v 1.207070 0.142910 3.428933 +v 1.264149 0.039097 3.452576 +v 1.245260 0.023645 3.725444 +v 1.170891 0.039097 3.700200 +v 1.206092 0.020326 3.712149 +v 1.298493 0.020326 3.466802 +v 1.498118 0.039097 2.978185 +v 1.443833 0.023645 3.246301 +v 1.373397 0.039097 3.211566 +v 1.406737 0.020326 3.228007 +v 1.530311 0.020326 2.996772 +v 2.910628 0.615620 1.381145 +v 2.196266 0.023645 2.196279 +v 2.045218 0.615620 2.045232 +v 2.097048 0.142910 2.097061 +v 1.854217 0.023645 2.586172 +v 1.742894 0.142910 2.500752 +v 1.791910 0.039097 2.538362 +v 1.703097 0.023645 2.797079 +v 1.637796 0.039097 2.753446 +v 1.668705 0.020326 2.774099 +v 1.821402 0.020326 2.560992 +v 2.140734 0.039097 2.140747 +v 2.018867 0.023645 2.385640 +v 1.959821 0.039097 2.333858 +v 1.987769 0.020326 2.358368 +v 2.167019 0.020326 2.167032 +v 2.947278 0.142910 1.444624 +v 2.586158 0.023645 1.854228 +v 2.500737 0.142910 1.742906 +v 2.538347 0.039097 1.791921 +v 2.385627 0.023645 2.018879 +v 2.333844 0.039097 1.959833 +v 2.358355 0.020326 1.987781 +v 2.560978 0.020326 1.821413 +v 2.978169 0.039097 1.498128 +v 2.797064 0.023645 1.703107 +v 2.753431 0.039097 1.637806 +v 2.774084 0.020326 1.668715 +v 2.996756 0.020326 1.530321 +v 1.117453 5.293516 5.000000 +v 3.058749 5.293516 1.637695 +v 1.637686 5.293516 3.058764 +v 0.974417 3.840676 5.000000 +v 1.513815 3.840676 2.987248 +v 2.987231 3.840676 1.513825 +v 1.897300 7.928881 3.208653 +v 1.254732 6.544681 5.000000 +v 1.756570 6.544681 3.127403 +v 3.127388 6.544681 1.756579 +v 9.124336 2.621381 5.000000 +v 6.982563 0.023645 1.566141 +v 7.062144 2.621381 1.428304 +v 5.000000 0.023645 1.034828 +v 5.000000 2.621381 0.875664 +v 5.000000 0.615620 0.821208 +v 3.973732 0.023645 1.169972 +v 3.918442 0.615620 0.963634 +v 3.937414 0.142910 1.034436 +v 3.482617 0.023645 1.336712 +v 3.428920 0.142910 1.207076 +v 3.452563 0.039097 1.264154 +v 3.246287 0.023645 1.443840 +v 3.211552 0.039097 1.373404 +v 3.227993 0.020326 1.406744 +v 3.466789 0.020326 1.298498 +v 3.953405 0.039097 1.094112 +v 3.725433 0.023645 1.245263 +v 3.700189 0.039097 1.170894 +v 3.712138 0.020326 1.206095 +v 3.963026 0.020326 1.130019 +v 5.000000 0.142910 0.894509 +v 4.482456 0.023645 1.068847 +v 4.464141 0.142910 0.929731 +v 4.472205 0.039097 0.990984 +v 4.226440 0.023645 1.111109 +v 4.211118 0.039097 1.034083 +v 4.218370 0.020326 1.070542 +v 4.477057 0.020326 1.027839 +v 5.000000 0.039097 0.956291 +v 4.740677 0.023645 1.043362 +v 4.735540 0.039097 0.964994 +v 4.737971 0.020326 1.002088 +v 5.000000 0.020326 0.993465 +v 7.089372 0.615620 1.381145 +v 6.026268 0.023645 1.169972 +v 6.081558 0.615620 0.963634 +v 6.062586 0.142910 1.034436 +v 5.517544 0.023645 1.068847 +v 5.535859 0.142910 0.929731 +v 5.527795 0.039097 0.990984 +v 5.259323 0.023645 1.043362 +v 5.264460 0.039097 0.964994 +v 5.262029 0.020326 1.002088 +v 5.522943 0.020326 1.027839 +v 6.046595 0.039097 1.094112 +v 5.773560 0.023645 1.111109 +v 5.788882 0.039097 1.034083 +v 5.781630 0.020326 1.070542 +v 6.036974 0.020326 1.130019 +v 7.052722 0.142910 1.444624 +v 6.517383 0.023645 1.336712 +v 6.571080 0.142910 1.207076 +v 6.547437 0.039097 1.264154 +v 6.274567 0.023645 1.245263 +v 6.299811 0.039097 1.170894 +v 6.287862 0.020326 1.206095 +v 6.533211 0.020326 1.298498 +v 7.021831 0.039097 1.498128 +v 6.753713 0.023645 1.443840 +v 6.788448 0.039097 1.373404 +v 6.772007 0.020326 1.406744 +v 7.003244 0.020326 1.530321 +v 8.433868 0.023645 3.017453 +v 8.571705 2.621381 2.937872 +v 8.618864 0.615620 2.910645 +v 7.803734 0.023645 2.196279 +v 7.954782 0.615620 2.045232 +v 7.902952 0.142910 2.097061 +v 7.413842 0.023645 1.854228 +v 7.499263 0.142910 1.742906 +v 7.461653 0.039097 1.791921 +v 7.202936 0.023645 1.703107 +v 7.246569 0.039097 1.637806 +v 7.225916 0.020326 1.668715 +v 7.439022 0.020326 1.821413 +v 7.859266 0.039097 2.140747 +v 7.614373 0.023645 2.018879 +v 7.666156 0.039097 1.959833 +v 7.641645 0.020326 1.987781 +v 7.832981 0.020326 2.167032 +v 8.555386 0.142910 2.947294 +v 8.145783 0.023645 2.586172 +v 8.257106 0.142910 2.500752 +v 8.208090 0.039097 2.538362 +v 7.981133 0.023645 2.385640 +v 8.040179 0.039097 2.333858 +v 8.012231 0.020326 2.358368 +v 8.178598 0.020326 2.560992 +v 8.501882 0.039097 2.978185 +v 8.296903 0.023645 2.797079 +v 8.362204 0.039097 2.753446 +v 8.331295 0.020326 2.774099 +v 8.469689 0.020326 2.996772 +v 9.178792 0.615620 5.000000 +v 8.830030 0.023645 3.973740 +v 9.036369 0.615620 3.918452 +v 8.965567 0.142910 3.937423 +v 8.663293 0.023645 3.482630 +v 8.792930 0.142910 3.428933 +v 8.735851 0.039097 3.452576 +v 8.556167 0.023645 3.246301 +v 8.626603 0.039097 3.211566 +v 8.593263 0.020326 3.228007 +v 8.701507 0.020326 3.466802 +v 8.905890 0.039097 3.953414 +v 8.754740 0.023645 3.725444 +v 8.829109 0.039097 3.700200 +v 8.793908 0.020326 3.712149 +v 8.869983 0.020326 3.963035 +v 9.105491 0.142910 5.000000 +v 8.931154 0.023645 4.482460 +v 9.070269 0.142910 4.464145 +v 9.009017 0.039097 4.472209 +v 8.888893 0.023645 4.226447 +v 8.965919 0.039097 4.211125 +v 8.929460 0.020326 4.218377 +v 8.972162 0.020326 4.477061 +v 9.043709 0.039097 5.000000 +v 8.956638 0.023645 4.740679 +v 9.035007 0.039097 4.735543 +v 8.997912 0.020326 4.737974 +v 9.006535 0.020326 5.000000 +v 6.791361 7.928881 1.897309 +v 6.941251 5.293516 1.637695 +v 5.000000 5.293516 1.117453 +v 5.000000 3.840676 0.974417 +v 7.012769 3.840676 1.513825 +v 5.000000 7.928881 1.417236 +v 5.000000 6.544681 1.254732 +v 6.872612 6.544681 1.756579 +v 8.882547 5.293516 5.000000 +v 8.362314 5.293516 3.058764 +v 8.486185 3.840676 2.987248 +v 9.025583 3.840676 5.000000 +v 8.102700 7.928881 3.208653 +v 8.243430 6.544681 3.127403 +v 8.745268 6.544681 5.000000 +v 3.739220 15.929955 2.816291 +v 1.753123 10.600694 5.000000 +v 3.376580 10.600694 2.188188 +v 2.188181 10.600694 3.376593 +v 1.575982 9.216277 5.000000 +v 2.034775 9.216277 3.288024 +v 3.288010 9.216277 2.034783 +v 2.109344 13.271226 5.000000 +v 3.554689 13.271226 2.496678 +v 2.496671 13.271226 3.554700 +v 1.924119 11.898438 5.000000 +v 2.336265 11.898438 3.462090 +v 3.462077 11.898438 2.336272 +v 2.816285 15.929955 3.739230 +v 2.288120 14.570229 5.000000 +v 2.651492 14.570229 3.644087 +v 3.644076 14.570229 2.651499 +v 8.246877 10.600694 5.000000 +v 6.623420 10.600694 2.188188 +v 5.000000 10.600694 1.753123 +v 5.000000 9.216277 1.575982 +v 6.711990 9.216277 2.034783 +v 7.811819 10.600694 3.376593 +v 7.965225 9.216277 3.288024 +v 8.424018 9.216277 5.000000 +v 6.260780 15.929955 2.816291 +v 6.445311 13.271226 2.496678 +v 5.000000 13.271226 2.109344 +v 5.000000 11.898438 1.924119 +v 6.537923 11.898438 2.336272 +v 5.000000 15.929955 2.478410 +v 5.000000 14.570229 2.288120 +v 6.355924 14.570229 2.651499 +v 7.890656 13.271226 5.000000 +v 7.503329 13.271226 3.554700 +v 7.663735 11.898438 3.462090 +v 8.075881 11.898438 5.000000 +v 7.183715 15.929955 3.739230 +v 7.348508 14.570229 3.644087 +v 7.711880 14.570229 5.000000 +v 6.982563 0.023645 8.433859 +v 6.791361 7.928881 8.102691 +v 7.062144 2.621381 8.571696 +v 8.433868 0.023645 6.982547 +v 8.571705 2.621381 7.062128 +v 8.618864 0.615620 7.089355 +v 8.830030 0.023645 6.026260 +v 9.036369 0.615620 6.081548 +v 8.965567 0.142910 6.062577 +v 8.931154 0.023645 5.517540 +v 9.070269 0.142910 5.535855 +v 9.009017 0.039097 5.527791 +v 8.956638 0.023645 5.259321 +v 9.035007 0.039097 5.264457 +v 8.997912 0.020326 5.262026 +v 8.972162 0.020326 5.522939 +v 8.905890 0.039097 6.046586 +v 8.888893 0.023645 5.773553 +v 8.965919 0.039097 5.788875 +v 8.929460 0.020326 5.781623 +v 8.869983 0.020326 6.036965 +v 8.555386 0.142910 7.052706 +v 8.663293 0.023645 6.517370 +v 8.792930 0.142910 6.571067 +v 8.735851 0.039097 6.547424 +v 8.754740 0.023645 6.274556 +v 8.829109 0.039097 6.299800 +v 8.793908 0.020326 6.287851 +v 8.701507 0.020326 6.533198 +v 8.501882 0.039097 7.021815 +v 8.556167 0.023645 6.753699 +v 8.626603 0.039097 6.788434 +v 8.593263 0.020326 6.771993 +v 8.469689 0.020326 7.003228 +v 7.089372 0.615620 8.618855 +v 7.803734 0.023645 7.803721 +v 7.954782 0.615620 7.954768 +v 7.902952 0.142910 7.902939 +v 8.145783 0.023645 7.413828 +v 8.257106 0.142910 7.499248 +v 8.208090 0.039097 7.461638 +v 8.296903 0.023645 7.202921 +v 8.362204 0.039097 7.246554 +v 8.331295 0.020326 7.225901 +v 8.178598 0.020326 7.439008 +v 7.859266 0.039097 7.859253 +v 7.981133 0.023645 7.614360 +v 8.040179 0.039097 7.666142 +v 8.012231 0.020326 7.641632 +v 7.832981 0.020326 7.832968 +v 7.052722 0.142910 8.555376 +v 7.413842 0.023645 8.145772 +v 7.499263 0.142910 8.257094 +v 7.461653 0.039097 8.208079 +v 7.614373 0.023645 7.981121 +v 7.666156 0.039097 8.040167 +v 7.641645 0.020326 8.012219 +v 7.439022 0.020326 8.178587 +v 7.021831 0.039097 8.501872 +v 7.202936 0.023645 8.296893 +v 7.246569 0.039097 8.362194 +v 7.225916 0.020326 8.331285 +v 7.003244 0.020326 8.469679 +v 6.941251 5.293516 8.362305 +v 8.362314 5.293516 6.941236 +v 8.486185 3.840676 7.012752 +v 7.012769 3.840676 8.486175 +v 8.102700 7.928881 6.791347 +v 8.243430 6.544681 6.872597 +v 6.872612 6.544681 8.243421 +v 3.017437 0.023645 8.433859 +v 2.937856 2.621381 8.571696 +v 5.000000 0.023645 8.965172 +v 5.000000 2.621381 9.124336 +v 5.000000 0.615620 9.178792 +v 6.026268 0.023645 8.830028 +v 6.081558 0.615620 9.036366 +v 6.062586 0.142910 8.965564 +v 6.517383 0.023645 8.663288 +v 6.571080 0.142910 8.792924 +v 6.547437 0.039097 8.735846 +v 6.753713 0.023645 8.556160 +v 6.788448 0.039097 8.626596 +v 6.772007 0.020326 8.593256 +v 6.533211 0.020326 8.701502 +v 6.046595 0.039097 8.905888 +v 6.274567 0.023645 8.754737 +v 6.299811 0.039097 8.829106 +v 6.287862 0.020326 8.793905 +v 6.036974 0.020326 8.869981 +v 5.000000 0.142910 9.105491 +v 5.517544 0.023645 8.931153 +v 5.535859 0.142910 9.070269 +v 5.527795 0.039097 9.009016 +v 5.773560 0.023645 8.888891 +v 5.788882 0.039097 8.965917 +v 5.781630 0.020326 8.929458 +v 5.522943 0.020326 8.972161 +v 5.000000 0.039097 9.043709 +v 5.259323 0.023645 8.956638 +v 5.264460 0.039097 9.035006 +v 5.262029 0.020326 8.997912 +v 5.000000 0.020326 9.006535 +v 2.910628 0.615620 8.618855 +v 3.973732 0.023645 8.830028 +v 3.918442 0.615620 9.036366 +v 3.937414 0.142910 8.965564 +v 4.482456 0.023645 8.931153 +v 4.464141 0.142910 9.070269 +v 4.472205 0.039097 9.009016 +v 4.740677 0.023645 8.956638 +v 4.735540 0.039097 9.035006 +v 4.737971 0.020326 8.997912 +v 4.477057 0.020326 8.972161 +v 3.953405 0.039097 8.905888 +v 4.226440 0.023645 8.888891 +v 4.211118 0.039097 8.965917 +v 4.218370 0.020326 8.929458 +v 3.963026 0.020326 8.869981 +v 2.947278 0.142910 8.555376 +v 3.482617 0.023645 8.663288 +v 3.428920 0.142910 8.792924 +v 3.452563 0.039097 8.735846 +v 3.725433 0.023645 8.754737 +v 3.700189 0.039097 8.829106 +v 3.712138 0.020326 8.793905 +v 3.466789 0.020326 8.701502 +v 2.978169 0.039097 8.501872 +v 3.246287 0.023645 8.556160 +v 3.211552 0.039097 8.626596 +v 3.227993 0.020326 8.593256 +v 2.996756 0.020326 8.469679 +v 1.566132 0.023645 6.982547 +v 1.428295 2.621381 7.062128 +v 1.381136 0.615620 7.089355 +v 2.196266 0.023645 7.803721 +v 2.045218 0.615620 7.954768 +v 2.097048 0.142910 7.902939 +v 2.586158 0.023645 8.145772 +v 2.500737 0.142910 8.257094 +v 2.538347 0.039097 8.208079 +v 2.797064 0.023645 8.296893 +v 2.753431 0.039097 8.362194 +v 2.774084 0.020326 8.331285 +v 2.560978 0.020326 8.178587 +v 2.140734 0.039097 7.859253 +v 2.385627 0.023645 7.981121 +v 2.333844 0.039097 8.040167 +v 2.358355 0.020326 8.012219 +v 2.167019 0.020326 7.832968 +v 1.444614 0.142910 7.052706 +v 1.854217 0.023645 7.413828 +v 1.742894 0.142910 7.499248 +v 1.791910 0.039097 7.461638 +v 2.018867 0.023645 7.614360 +v 1.959821 0.039097 7.666142 +v 1.987769 0.020326 7.641632 +v 1.821402 0.020326 7.439008 +v 1.498118 0.039097 7.021815 +v 1.703097 0.023645 7.202921 +v 1.637796 0.039097 7.246554 +v 1.668705 0.020326 7.225901 +v 1.530311 0.020326 7.003228 +v 1.169970 0.023645 6.026260 +v 0.963631 0.615620 6.081548 +v 1.034433 0.142910 6.062577 +v 1.336707 0.023645 6.517370 +v 1.207070 0.142910 6.571067 +v 1.264149 0.039097 6.547424 +v 1.443833 0.023645 6.753699 +v 1.373397 0.039097 6.788434 +v 1.406737 0.020326 6.771993 +v 1.298493 0.020326 6.533198 +v 1.094110 0.039097 6.046586 +v 1.245260 0.023645 6.274556 +v 1.170891 0.039097 6.299800 +v 1.206092 0.020326 6.287851 +v 1.130017 0.020326 6.036965 +v 3.208639 7.928881 8.102691 +v 3.058749 5.293516 8.362305 +v 5.000000 5.293516 8.882547 +v 5.000000 3.840676 9.025583 +v 2.987231 3.840676 8.486175 +v 5.000000 7.928881 8.582764 +v 5.000000 6.544681 8.745268 +v 3.127388 6.544681 8.243421 +v 1.637686 5.293516 6.941236 +v 1.513815 3.840676 7.012752 +v 1.897300 7.928881 6.791347 +v 1.756570 6.544681 6.872597 +v 6.260780 15.929955 7.183709 +v 6.623420 10.600694 7.811812 +v 7.811819 10.600694 6.623407 +v 7.965225 9.216277 6.711976 +v 6.711990 9.216277 7.965217 +v 6.445311 13.271226 7.503322 +v 7.503329 13.271226 6.445300 +v 7.663735 11.898438 6.537910 +v 6.537923 11.898438 7.663728 +v 7.183715 15.929955 6.260770 +v 7.348508 14.570229 6.355913 +v 6.355924 14.570229 7.348501 +v 3.376580 10.600694 7.811812 +v 5.000000 10.600694 8.246877 +v 5.000000 9.216277 8.424018 +v 3.288010 9.216277 7.965217 +v 2.188181 10.600694 6.623407 +v 2.034775 9.216277 6.711976 +v 3.739220 15.929955 7.183709 +v 3.554689 13.271226 7.503322 +v 5.000000 13.271226 7.890656 +v 5.000000 11.898438 8.075881 +v 3.462077 11.898438 7.663728 +v 5.000000 15.929955 7.521590 +v 5.000000 14.570229 7.711880 +v 3.644076 14.570229 7.348501 +v 2.496671 13.271226 6.445300 +v 2.336265 11.898438 6.537910 +v 2.816285 15.929955 6.260770 +v 2.651492 14.570229 6.355913 +vt 1.000000 0.916667 +vt 1.000000 1.000000 +vt 0.957053 0.916667 +vt 1.000000 0.416667 +vt 1.000000 0.500000 +vt 0.957053 0.416667 +vt 0.710046 0.416667 +vt 0.710046 0.500000 +vt 0.646478 0.416667 +vt 0.710046 0.083333 +vt 0.710046 0.166666 +vt 0.646478 0.083333 +vt 0.414458 0.083333 +vt 0.414458 0.166666 +vt 0.207229 0.166666 +vt 0.207229 0.000000 +vt 0.414458 0.000000 +vt 0.207229 0.083333 +vt 0.103615 0.083333 +vt 0.103615 0.062500 +vt 0.207229 0.041667 +vt 0.103615 0.041667 +vt 0.103615 0.020833 +vt 0.051807 0.041667 +vt 0.051807 0.031250 +vt 0.051807 0.020833 +vt 0.051807 0.010417 +vt 0.025904 0.010417 +vt 0.025904 0.000000 +vt 0.051807 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.010417 +vt 0.025904 0.020833 +vt 0.025904 0.031250 +vt 0.000000 0.020833 +vt 0.000000 0.031250 +vt 0.025904 0.041667 +vt 0.051807 0.083333 +vt 0.051807 0.072916 +vt 0.051807 0.062500 +vt 0.051807 0.052083 +vt 0.025904 0.052083 +vt 0.000000 0.041667 +vt 0.000000 0.052083 +vt 0.025904 0.062500 +vt 0.025904 0.072916 +vt 0.000000 0.062500 +vt 0.000000 0.072916 +vt 0.025904 0.083333 +vt 0.103615 0.145833 +vt 0.103615 0.125000 +vt 0.207229 0.125000 +vt 0.103615 0.104166 +vt 0.051807 0.125000 +vt 0.051807 0.114583 +vt 0.051807 0.104166 +vt 0.051807 0.093750 +vt 0.025904 0.093750 +vt 0.000000 0.083333 +vt 0.000000 0.093750 +vt 0.025904 0.104166 +vt 0.025904 0.114583 +vt 0.000000 0.104166 +vt 0.000000 0.114583 +vt 0.025904 0.125000 +vt 0.103615 0.166666 +vt 0.051807 0.166666 +vt 0.051807 0.156250 +vt 0.051807 0.145833 +vt 0.051807 0.135416 +vt 0.025904 0.135416 +vt 0.000000 0.125000 +vt 0.000000 0.135416 +vt 0.025904 0.145833 +vt 0.025904 0.156250 +vt 0.000000 0.145833 +vt 0.000000 0.156250 +vt 0.025904 0.166666 +vt 0.582909 0.083333 +vt 0.582909 0.166666 +vt 0.498684 0.083333 +vt 0.498684 0.000000 +vt 0.582909 0.000000 +vt 0.498684 0.166666 +vt 0.646478 0.000000 +vt 0.710046 0.000000 +vt 0.646478 0.166666 +vt 0.207229 0.458333 +vt 0.207229 0.416667 +vt 0.414458 0.416667 +vt 0.207229 0.250000 +vt 0.414458 0.250000 +vt 0.414458 0.333334 +vt 0.103615 0.250000 +vt 0.103615 0.229167 +vt 0.207229 0.208333 +vt 0.103615 0.208333 +vt 0.103615 0.187500 +vt 0.051807 0.208333 +vt 0.051807 0.197916 +vt 0.051807 0.187500 +vt 0.051807 0.177083 +vt 0.025904 0.177083 +vt 0.000000 0.166666 +vt 0.000000 0.177083 +vt 0.025904 0.187500 +vt 0.025904 0.197916 +vt 0.000000 0.187500 +vt 0.000000 0.197916 +vt 0.025904 0.208333 +vt 0.051807 0.250000 +vt 0.051807 0.239583 +vt 0.051807 0.229167 +vt 0.051807 0.218750 +vt 0.025904 0.218750 +vt 0.000000 0.208333 +vt 0.000000 0.218750 +vt 0.025904 0.229167 +vt 0.025904 0.239583 +vt 0.000000 0.229167 +vt 0.000000 0.239583 +vt 0.025904 0.250000 +vt 0.207229 0.333334 +vt 0.103615 0.333334 +vt 0.103615 0.312500 +vt 0.207229 0.291667 +vt 0.103615 0.291667 +vt 0.103615 0.270833 +vt 0.051807 0.291667 +vt 0.051807 0.281250 +vt 0.051807 0.270833 +vt 0.051807 0.260417 +vt 0.025904 0.260417 +vt 0.000000 0.250000 +vt 0.000000 0.260417 +vt 0.025904 0.270833 +vt 0.025904 0.281250 +vt 0.000000 0.270833 +vt 0.000000 0.281250 +vt 0.025904 0.291667 +vt 0.051807 0.333334 +vt 0.051807 0.322917 +vt 0.051807 0.312500 +vt 0.051807 0.302084 +vt 0.025904 0.302084 +vt 0.000000 0.291667 +vt 0.000000 0.302084 +vt 0.025904 0.312500 +vt 0.025904 0.322917 +vt 0.000000 0.312500 +vt 0.000000 0.322917 +vt 0.025904 0.333334 +vt 0.103615 0.416667 +vt 0.103615 0.395834 +vt 0.207229 0.375000 +vt 0.103615 0.375000 +vt 0.103615 0.354167 +vt 0.051807 0.375000 +vt 0.051807 0.364584 +vt 0.051807 0.354167 +vt 0.051807 0.343750 +vt 0.025904 0.343750 +vt 0.000000 0.333334 +vt 0.000000 0.343750 +vt 0.025904 0.354167 +vt 0.025904 0.364584 +vt 0.000000 0.354167 +vt 0.000000 0.364584 +vt 0.025904 0.375000 +vt 0.051807 0.416667 +vt 0.051807 0.406250 +vt 0.051807 0.395834 +vt 0.051807 0.385417 +vt 0.025904 0.385417 +vt 0.000000 0.375000 +vt 0.000000 0.385417 +vt 0.025904 0.395834 +vt 0.025904 0.406250 +vt 0.000000 0.395834 +vt 0.000000 0.406250 +vt 0.025904 0.416667 +vt 0.103615 0.479167 +vt 0.103615 0.458333 +vt 0.103615 0.437500 +vt 0.051807 0.458333 +vt 0.051807 0.447917 +vt 0.051807 0.437500 +vt 0.051807 0.427084 +vt 0.025904 0.427084 +vt 0.000000 0.416667 +vt 0.000000 0.427084 +vt 0.025904 0.437500 +vt 0.025904 0.447917 +vt 0.000000 0.437500 +vt 0.000000 0.447917 +vt 0.025904 0.458333 +vt 0.051807 0.489583 +vt 0.051807 0.479167 +vt 0.051807 0.468750 +vt 0.025904 0.468750 +vt 0.000000 0.458333 +vt 0.000000 0.468750 +vt 0.025904 0.479167 +vt 0.025904 0.489583 +vt 0.051807 0.500000 +vt 0.000000 0.479167 +vt 0.000000 0.489583 +vt 0.025904 0.500000 +vt 0.710046 0.250000 +vt 0.710046 0.333334 +vt 0.646478 0.250000 +vt 0.498684 0.250000 +vt 0.582909 0.250000 +vt 0.582909 0.333334 +vt 0.498684 0.333334 +vt 0.646478 0.333334 +vt 0.498684 0.416667 +vt 0.582909 0.416667 +vt 0.582909 0.500000 +vt 0.498684 0.500000 +vt 0.646478 0.500000 +vt 1.000000 0.083333 +vt 1.000000 0.166666 +vt 0.957053 0.083333 +vt 0.818618 0.083333 +vt 0.818618 0.166666 +vt 0.764332 0.083333 +vt 0.764332 0.000000 +vt 0.818618 0.000000 +vt 0.764332 0.166666 +vt 0.914105 0.083333 +vt 0.914105 0.166666 +vt 0.866362 0.083333 +vt 0.866362 0.000000 +vt 0.914105 0.000000 +vt 0.866362 0.166666 +vt 0.957053 0.000000 +vt 1.000000 0.000000 +vt 0.957053 0.166666 +vt 0.764332 0.416667 +vt 0.818618 0.416667 +vt 0.818618 0.500000 +vt 0.764332 0.250000 +vt 0.818618 0.250000 +vt 0.818618 0.333334 +vt 0.764332 0.333334 +vt 0.764332 0.500000 +vt 1.000000 0.250000 +vt 1.000000 0.333334 +vt 0.957053 0.250000 +vt 0.866362 0.250000 +vt 0.914105 0.250000 +vt 0.914105 0.333334 +vt 0.866362 0.333334 +vt 0.957053 0.333334 +vt 0.866362 0.416667 +vt 0.914105 0.416667 +vt 0.914105 0.500000 +vt 0.866362 0.500000 +vt 0.957053 0.500000 +vt 0.646478 0.916667 +vt 0.710046 0.916667 +vt 0.710046 1.000000 +vt 0.710046 0.583333 +vt 0.710046 0.666666 +vt 0.646478 0.583333 +vt 0.414458 0.583333 +vt 0.414458 0.666666 +vt 0.207229 0.666666 +vt 0.207229 0.500000 +vt 0.414458 0.500000 +vt 0.207229 0.583333 +vt 0.103615 0.583333 +vt 0.103615 0.562500 +vt 0.207229 0.541667 +vt 0.103615 0.541667 +vt 0.103615 0.520833 +vt 0.051807 0.541667 +vt 0.051807 0.531250 +vt 0.051807 0.520833 +vt 0.051807 0.510417 +vt 0.025904 0.510417 +vt 0.000000 0.500000 +vt 0.000000 0.510417 +vt 0.025904 0.520833 +vt 0.025904 0.531250 +vt 0.000000 0.520833 +vt 0.000000 0.531250 +vt 0.025904 0.541667 +vt 0.051807 0.583333 +vt 0.051807 0.572916 +vt 0.051807 0.562500 +vt 0.051807 0.552083 +vt 0.025904 0.552083 +vt 0.000000 0.541667 +vt 0.000000 0.552083 +vt 0.025904 0.562500 +vt 0.025904 0.572916 +vt 0.000000 0.562500 +vt 0.000000 0.572916 +vt 0.025904 0.583333 +vt 0.103615 0.666666 +vt 0.103615 0.645833 +vt 0.207229 0.625000 +vt 0.103615 0.625000 +vt 0.103615 0.604166 +vt 0.051807 0.625000 +vt 0.051807 0.614583 +vt 0.051807 0.604166 +vt 0.051807 0.593750 +vt 0.025904 0.593750 +vt 0.000000 0.583333 +vt 0.000000 0.593750 +vt 0.025904 0.604166 +vt 0.025904 0.614583 +vt 0.000000 0.604166 +vt 0.000000 0.614583 +vt 0.025904 0.625000 +vt 0.051807 0.666666 +vt 0.051807 0.656250 +vt 0.051807 0.645833 +vt 0.051807 0.635416 +vt 0.025904 0.635416 +vt 0.000000 0.625000 +vt 0.000000 0.635416 +vt 0.025904 0.645833 +vt 0.025904 0.656250 +vt 0.000000 0.645833 +vt 0.000000 0.656250 +vt 0.025904 0.666666 +vt 0.582909 0.583333 +vt 0.582909 0.666666 +vt 0.498684 0.583333 +vt 0.498684 0.666666 +vt 0.646478 0.666666 +vt 0.207229 0.958333 +vt 0.207229 0.916667 +vt 0.414458 0.916667 +vt 0.207229 0.750000 +vt 0.414458 0.750000 +vt 0.414458 0.833334 +vt 0.103615 0.750000 +vt 0.103615 0.729167 +vt 0.207229 0.708333 +vt 0.103615 0.708333 +vt 0.103615 0.687500 +vt 0.051807 0.708333 +vt 0.051807 0.697916 +vt 0.051807 0.687500 +vt 0.051807 0.677083 +vt 0.025904 0.677083 +vt 0.000000 0.666666 +vt 0.000000 0.677083 +vt 0.025904 0.687500 +vt 0.025904 0.697916 +vt 0.000000 0.687500 +vt 0.000000 0.697916 +vt 0.025904 0.708333 +vt 0.051807 0.750000 +vt 0.051807 0.739583 +vt 0.051807 0.729167 +vt 0.051807 0.718750 +vt 0.025904 0.718750 +vt 0.000000 0.708333 +vt 0.000000 0.718750 +vt 0.025904 0.729167 +vt 0.025904 0.739583 +vt 0.000000 0.729167 +vt 0.000000 0.739583 +vt 0.025904 0.750000 +vt 0.207229 0.833334 +vt 0.103615 0.833334 +vt 0.103615 0.812500 +vt 0.207229 0.791667 +vt 0.103615 0.791667 +vt 0.103615 0.770833 +vt 0.051807 0.791667 +vt 0.051807 0.781250 +vt 0.051807 0.770833 +vt 0.051807 0.760417 +vt 0.025904 0.760417 +vt 0.000000 0.750000 +vt 0.000000 0.760417 +vt 0.025904 0.770833 +vt 0.025904 0.781250 +vt 0.000000 0.770833 +vt 0.000000 0.781250 +vt 0.025904 0.791667 +vt 0.051807 0.833334 +vt 0.051807 0.822917 +vt 0.051807 0.812500 +vt 0.051807 0.802084 +vt 0.025904 0.802084 +vt 0.000000 0.791667 +vt 0.000000 0.802084 +vt 0.025904 0.812500 +vt 0.025904 0.822917 +vt 0.000000 0.812500 +vt 0.000000 0.822917 +vt 0.025904 0.833334 +vt 0.103615 0.916667 +vt 0.103615 0.895834 +vt 0.207229 0.875000 +vt 0.103615 0.875000 +vt 0.103615 0.854167 +vt 0.051807 0.875000 +vt 0.051807 0.864584 +vt 0.051807 0.854167 +vt 0.051807 0.843750 +vt 0.025904 0.843750 +vt 0.000000 0.833334 +vt 0.000000 0.843750 +vt 0.025904 0.854167 +vt 0.025904 0.864584 +vt 0.000000 0.854167 +vt 0.000000 0.864584 +vt 0.025904 0.875000 +vt 0.051807 0.916667 +vt 0.051807 0.906250 +vt 0.051807 0.895834 +vt 0.051807 0.885417 +vt 0.025904 0.885417 +vt 0.000000 0.875000 +vt 0.000000 0.885417 +vt 0.025904 0.895834 +vt 0.025904 0.906250 +vt 0.000000 0.895834 +vt 0.000000 0.906250 +vt 0.025904 0.916667 +vt 0.103615 0.958333 +vt 0.207229 1.000000 +vt 0.103615 0.937500 +vt 0.051807 0.958333 +vt 0.051807 0.947917 +vt 0.051807 0.937500 +vt 0.051807 0.927084 +vt 0.025904 0.927084 +vt 0.000000 0.916667 +vt 0.000000 0.927084 +vt 0.025904 0.937500 +vt 0.025904 0.947917 +vt 0.000000 0.937500 +vt 0.000000 0.947917 +vt 0.025904 0.958333 +vt 0.000000 1.000000 +vt 0.000000 0.958333 +vt 0.710046 0.750000 +vt 0.710046 0.833334 +vt 0.646478 0.750000 +vt 0.498684 0.750000 +vt 0.582909 0.750000 +vt 0.582909 0.833334 +vt 0.498684 0.833334 +vt 0.646478 0.833334 +vt 0.498684 0.916667 +vt 0.582909 0.916667 +vt 0.582909 1.000000 +vt 0.498684 1.000000 +vt 0.646478 1.000000 +vt 1.000000 0.583333 +vt 1.000000 0.666666 +vt 0.957053 0.583333 +vt 0.764332 0.583333 +vt 0.818618 0.583333 +vt 0.818618 0.666666 +vt 0.764332 0.666666 +vt 0.866362 0.583333 +vt 0.914105 0.583333 +vt 0.914105 0.666666 +vt 0.866362 0.666666 +vt 0.957053 0.666666 +vt 0.764332 0.916667 +vt 0.818618 0.916667 +vt 0.818618 1.000000 +vt 0.764332 0.750000 +vt 0.818618 0.750000 +vt 0.818618 0.833334 +vt 0.764332 0.833334 +vt 0.764332 1.000000 +vt 1.000000 0.750000 +vt 1.000000 0.833334 +vt 0.957053 0.750000 +vt 0.866362 0.750000 +vt 0.914105 0.750000 +vt 0.914105 0.833334 +vt 0.866362 0.833334 +vt 0.957053 0.833334 +vt 0.866362 0.916667 +vt 0.914105 0.916667 +vt 0.914105 1.000000 +vt 0.866362 1.000000 +vt 0.957053 1.000000 +vt 0.103615 0.000000 +vt 0.103615 0.500000 +vt 0.414458 1.000000 +vt 0.103615 1.000000 +vt 0.051807 1.000000 +vt 0.025904 1.000000 +vn -0.855158 0.138592 0.499497 +vn -0.990337 0.138595 0.004983 +vn -0.855477 0.137445 0.499267 +vn 0.855158 0.138592 -0.499497 +vn 0.990337 0.138595 -0.004983 +vn 0.855477 0.137445 -0.499267 +vn 0.858038 0.119287 -0.499541 +vn 0.992853 0.119290 -0.003582 +vn 0.858835 0.112906 -0.499655 +vn -0.861619 0.119288 -0.493338 +vn -0.499543 0.119288 -0.858037 +vn -0.862116 0.112906 -0.493972 +vn -0.864783 0.062737 -0.498211 +vn -0.522059 0.054243 -0.851183 +vn -0.559013 0.035015 -0.828420 +vn -0.998818 0.048476 0.003588 +vn -0.998889 0.047128 0.000794 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.848748 -0.198912 -0.489960 +vn -0.915190 -0.136671 -0.379143 +vn -0.970776 0.085464 -0.224254 +vn -0.946638 -0.198907 -0.253600 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.753817 -0.625309 -0.201863 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.773684 -0.625316 -0.101943 +vn -0.834536 -0.548214 -0.054865 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.774567 -0.626221 0.088845 +vn -0.834536 -0.548214 -0.054865 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.199250 -0.979861 -0.013125 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.753817 -0.625309 -0.201863 +vn -0.197953 -0.979864 -0.026106 +vn -0.773684 -0.625316 -0.101943 +vn -0.820199 -0.548350 -0.163050 +vn 0.079314 -0.996795 0.010461 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn -0.195829 -0.979864 -0.038953 +vn -0.192889 -0.979859 -0.051676 +vn -0.848748 -0.198912 -0.489960 +vn -0.675878 -0.625313 -0.390093 +vn -0.749973 -0.548375 -0.369898 +vn -0.915190 -0.136671 -0.379143 +vn -0.720908 -0.625314 -0.298787 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.192889 -0.979859 -0.051676 +vn -0.753817 -0.625309 -0.201863 +vn -0.792045 -0.548040 -0.268918 +vn 0.077272 -0.996795 0.020703 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn -0.189096 -0.979856 -0.064228 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.675878 -0.625313 -0.390093 +vn -0.184454 -0.979861 -0.076474 +vn -0.720908 -0.625314 -0.298787 +vn -0.749973 -0.548375 -0.369898 +vn 0.073898 -0.996795 0.030640 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn -0.179057 -0.979865 -0.088341 +vn -0.172924 -0.979863 -0.099831 +vn -0.603081 -0.136554 -0.785905 +vn -0.692977 -0.198918 -0.692975 +vn -0.679581 0.085468 -0.728605 +vn -0.679581 0.085468 -0.728605 +vn -0.692977 -0.198918 -0.692975 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.551796 -0.625317 -0.551816 +vn -0.628648 -0.548296 -0.551520 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.619062 -0.625306 -0.475137 +vn -0.172924 -0.979863 -0.099831 +vn -0.675878 -0.625313 -0.390093 +vn -0.695502 -0.548117 -0.464591 +vn 0.069281 -0.996795 0.039999 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn -0.166042 -0.979858 -0.110944 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.551796 -0.625317 -0.551816 +vn -0.158405 -0.979857 -0.121607 +vn -0.619062 -0.625306 -0.475137 +vn -0.628648 -0.548296 -0.551520 +vn 0.063454 -0.996795 0.048715 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn -0.150082 -0.979862 -0.131702 +vn -0.141165 -0.979865 -0.141202 +vn -0.489963 -0.198913 -0.848746 +vn -0.390067 -0.625315 -0.675892 +vn -0.464580 -0.548113 -0.695513 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.475115 -0.625305 -0.619080 +vn -0.141165 -0.979865 -0.141202 +vn -0.551796 -0.625317 -0.551816 +vn -0.551508 -0.548294 -0.628659 +vn 0.056560 -0.996795 0.056577 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn -0.131662 -0.979863 -0.150115 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.390067 -0.625315 -0.675892 +vn -0.121566 -0.979857 -0.158438 +vn -0.475115 -0.625305 -0.619080 +vn -0.464580 -0.548113 -0.695513 +vn 0.048696 -0.996795 0.063468 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn -0.110900 -0.979858 -0.166071 +vn -0.099785 -0.979863 -0.172949 +vn -0.862907 0.102956 -0.494765 +vn -0.499945 0.102956 -0.859916 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.994681 0.102958 0.002990 +vn -0.862907 0.102956 -0.494765 +vn -0.998889 0.047128 0.000794 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.863780 0.089908 -0.495782 +vn -0.500192 0.089907 -0.861234 +vn -0.993600 0.112908 0.003282 +vn -0.992853 0.119290 0.003582 +vn -0.861619 0.119288 -0.493338 +vn -0.994681 0.102958 0.002990 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.862116 0.112906 -0.493972 +vn -0.499657 0.112906 -0.858834 +vn 0.970776 0.085464 -0.224254 +vn 0.865986 0.007573 -0.500011 +vn 0.863839 0.062737 -0.499846 +vn -0.000000 0.054620 -0.998507 +vn -0.000794 0.047128 -0.998889 +vn 0.520588 0.054246 -0.852083 +vn -0.522059 0.054243 -0.851183 +vn -0.000794 0.047128 -0.998889 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.000000 -0.198908 -0.980018 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.253603 -0.198906 -0.946637 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.201834 -0.625309 -0.753825 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.298761 -0.625313 -0.720920 +vn -0.099785 -0.979863 -0.172949 +vn -0.390067 -0.625315 -0.675892 +vn -0.369884 -0.548374 -0.749982 +vn 0.039978 -0.996795 0.069293 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn -0.088294 -0.979865 -0.179080 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.201834 -0.625309 -0.753825 +vn -0.076426 -0.979861 -0.184474 +vn -0.298761 -0.625313 -0.720920 +vn -0.268901 -0.548039 -0.792052 +vn 0.030617 -0.996795 0.073907 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn -0.064178 -0.979856 -0.189113 +vn -0.051625 -0.979859 -0.192902 +vn 0.000000 -0.198908 -0.980018 +vn 0.000016 -0.625302 -0.780383 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn -0.101911 -0.625316 -0.773688 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.051625 -0.979859 -0.192902 +vn -0.201834 -0.625309 -0.753825 +vn -0.163032 -0.548348 -0.820204 +vn 0.020680 -0.996795 0.077279 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn -0.038902 -0.979864 -0.195841 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn 0.000016 -0.625302 -0.780383 +vn -0.026053 -0.979864 -0.197959 +vn -0.101911 -0.625316 -0.773688 +vn -0.054845 -0.548214 -0.834538 +vn 0.010437 -0.996795 0.079315 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn -0.013072 -0.979860 -0.199255 +vn 0.000027 -0.979855 -0.199708 +vn 0.559013 0.035015 -0.828420 +vn 0.489963 -0.198913 -0.848746 +vn 0.379146 -0.136670 -0.915188 +vn 0.224256 0.085466 -0.970775 +vn 0.253603 -0.198906 -0.946637 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.201864 -0.625309 -0.753817 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.101942 -0.625316 -0.773684 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.000027 -0.979855 -0.199708 +vn 0.000016 -0.625302 -0.780383 +vn 0.054866 -0.548214 -0.834537 +vn -0.000012 -0.996795 0.079997 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn 0.013125 -0.979860 -0.199252 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.201864 -0.625309 -0.753817 +vn 0.026105 -0.979864 -0.197952 +vn 0.101942 -0.625316 -0.773684 +vn 0.163052 -0.548348 -0.820200 +vn -0.010461 -0.996795 0.079312 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn 0.038954 -0.979864 -0.195830 +vn 0.051676 -0.979859 -0.192887 +vn 0.489963 -0.198913 -0.848746 +vn 0.390094 -0.625314 -0.675876 +vn 0.369902 -0.548374 -0.749972 +vn 0.379146 -0.136670 -0.915188 +vn 0.298790 -0.625312 -0.720908 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.051676 -0.979859 -0.192887 +vn 0.201864 -0.625309 -0.753817 +vn 0.268920 -0.548039 -0.792045 +vn -0.020704 -0.996795 0.077272 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn 0.064229 -0.979856 -0.189096 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.390094 -0.625314 -0.675876 +vn 0.076475 -0.979861 -0.184454 +vn 0.298790 -0.625312 -0.720908 +vn 0.369902 -0.548374 -0.749972 +vn -0.030640 -0.996795 0.073898 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn 0.088341 -0.979865 -0.179057 +vn 0.099830 -0.979863 -0.172922 +vn 0.559013 0.035015 -0.828420 +vn 0.520588 0.054246 -0.852083 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.848748 -0.198912 -0.489960 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.692977 -0.198918 -0.692975 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551819 -0.625315 -0.551794 +vn 0.551523 -0.548295 -0.628645 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.475140 -0.625305 -0.619061 +vn 0.099830 -0.979863 -0.172922 +vn 0.390094 -0.625314 -0.675876 +vn 0.464597 -0.548113 -0.695501 +vn -0.039999 -0.996795 0.069281 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn 0.110944 -0.979858 -0.166042 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.551819 -0.625315 -0.551794 +vn 0.121608 -0.979857 -0.158406 +vn 0.475140 -0.625305 -0.619061 +vn 0.551523 -0.548295 -0.628645 +vn -0.048715 -0.996795 0.063453 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn 0.131702 -0.979863 -0.150080 +vn 0.141203 -0.979865 -0.141164 +vn 0.848748 -0.198912 -0.489960 +vn 0.675893 -0.625315 -0.390065 +vn 0.695513 -0.548117 -0.464574 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.619082 -0.625304 -0.475112 +vn 0.141203 -0.979865 -0.141164 +vn 0.551819 -0.625315 -0.551794 +vn 0.628661 -0.548296 -0.551504 +vn -0.056577 -0.996795 0.056559 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn 0.150116 -0.979863 -0.131661 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.675893 -0.625315 -0.390065 +vn 0.158439 -0.979857 -0.121565 +vn 0.619082 -0.625304 -0.475112 +vn 0.695513 -0.548117 -0.464574 +vn -0.063469 -0.996795 0.048696 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn 0.166073 -0.979858 -0.110900 +vn 0.172949 -0.979863 -0.099784 +vn 0.982121 -0.136787 -0.129332 +vn 0.946638 -0.198907 -0.253600 +vn 0.970776 0.085464 -0.224254 +vn 0.970776 0.085464 -0.224254 +vn 0.946638 -0.198907 -0.253600 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.753824 -0.625311 -0.201832 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.720921 -0.625312 -0.298759 +vn 0.172949 -0.979863 -0.099784 +vn 0.675893 -0.625315 -0.390065 +vn 0.749983 -0.548375 -0.369880 +vn -0.069293 -0.996795 0.039977 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn 0.179081 -0.979865 -0.088293 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.753824 -0.625311 -0.201832 +vn 0.184475 -0.979861 -0.076425 +vn 0.720921 -0.625312 -0.298759 +vn 0.792052 -0.548040 -0.268898 +vn -0.073908 -0.996795 0.030617 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn 0.189113 -0.979856 -0.064178 +vn 0.192902 -0.979859 -0.051624 +vn 0.834538 -0.548214 -0.054844 +vn 0.773688 -0.625316 -0.101912 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.773688 -0.625316 -0.101912 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.192902 -0.979859 -0.051624 +vn 0.753824 -0.625311 -0.201832 +vn 0.820204 -0.548349 -0.163030 +vn -0.077279 -0.996795 0.020680 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn 0.195842 -0.979864 -0.038902 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.780383 -0.625302 0.000016 +vn 0.197959 -0.979864 -0.026053 +vn 0.773688 -0.625316 -0.101912 +vn 0.834538 -0.548214 -0.054844 +vn -0.079316 -0.996795 0.010437 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn 0.199256 -0.979860 -0.013072 +vn 0.199709 -0.979855 0.000026 +vn -0.003582 0.119290 -0.992853 +vn 0.493340 0.119288 -0.861618 +vn -0.003282 0.112908 -0.993600 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn 0.494767 0.102956 -0.862905 +vn -0.500192 0.089907 -0.861234 +vn -0.499945 0.102956 -0.859916 +vn -0.002990 0.102958 -0.994681 +vn -0.522059 0.054243 -0.851183 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.002546 0.089909 -0.995947 +vn 0.495785 0.089908 -0.863779 +vn -0.499543 0.119288 -0.858037 +vn -0.003582 0.119290 -0.992853 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.003282 0.112908 -0.993600 +vn 0.493974 0.112906 -0.862115 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.994681 0.102958 -0.002990 +vn 0.495785 0.089908 -0.863779 +vn 0.494767 0.102956 -0.862905 +vn 0.859917 0.102956 -0.499943 +vn 0.520588 0.054246 -0.852083 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.861235 0.089907 -0.500190 +vn 0.995947 0.089909 -0.002546 +vn 0.493340 0.119288 -0.861618 +vn 0.858038 0.119287 -0.499541 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.858835 0.112906 -0.499655 +vn 0.993600 0.112908 -0.003282 +vn -0.860140 0.138592 -0.490867 +vn -0.499499 0.138592 -0.855157 +vn -0.860102 0.137445 -0.491258 +vn -0.860841 0.128646 -0.492344 +vn -0.499366 0.128646 -0.856787 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.991682 0.128649 0.004054 +vn -0.860841 0.128646 -0.492344 +vn -0.992853 0.119290 0.003582 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.861162 0.124651 -0.492811 +vn -0.499410 0.124651 -0.857352 +vn -0.860318 0.134936 -0.491574 +vn -0.499299 0.134937 -0.855858 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.990844 0.134939 0.004460 +vn -0.860318 0.134936 -0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.860532 0.132157 -0.491955 +vn -0.499292 0.132157 -0.856295 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.860140 0.138592 -0.490867 +vn -0.990844 0.134939 0.004460 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.860102 0.137445 -0.491258 +vn -0.499269 0.137445 -0.855476 +vn 0.857353 0.124650 -0.499408 +vn 0.856788 0.128646 -0.499364 +vn 0.991682 0.128649 -0.004054 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn 0.492346 0.128646 -0.860840 +vn -0.499410 0.124651 -0.857352 +vn -0.499366 0.128646 -0.856787 +vn -0.004054 0.128649 -0.991682 +vn -0.499543 0.119288 -0.858037 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.003810 0.124653 -0.992193 +vn 0.492814 0.124651 -0.861160 +vn 0.492814 0.124651 -0.861160 +vn 0.492346 0.128646 -0.860840 +vn 0.856788 0.128646 -0.499364 +vn 0.493340 0.119288 -0.861618 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.857353 0.124650 -0.499408 +vn 0.992193 0.124653 -0.003810 +vn -0.004983 0.138595 -0.990337 +vn 0.490869 0.138592 -0.860139 +vn -0.004625 0.137448 -0.990498 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn 0.491576 0.134936 -0.860317 +vn -0.499292 0.132157 -0.856295 +vn -0.499299 0.134937 -0.855858 +vn -0.004460 0.134939 -0.990844 +vn -0.499366 0.128646 -0.856787 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.004236 0.132159 -0.991220 +vn 0.491957 0.132157 -0.860530 +vn -0.499499 0.138592 -0.855157 +vn -0.004983 0.138595 -0.990337 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.004625 0.137448 -0.990498 +vn 0.491260 0.137445 -0.860100 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.990844 0.134939 -0.004460 +vn 0.491957 0.132157 -0.860530 +vn 0.491576 0.134936 -0.860317 +vn 0.855859 0.134936 -0.499297 +vn 0.492346 0.128646 -0.860840 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.856296 0.132157 -0.499291 +vn 0.991220 0.132159 -0.004236 +vn 0.490869 0.138592 -0.860139 +vn 0.855158 0.138592 -0.499497 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.855477 0.137445 -0.499267 +vn 0.990498 0.137448 -0.004625 +vn -0.858835 0.112906 0.499655 +vn -0.858038 0.119288 0.499541 +vn -0.992853 0.119290 0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.499543 0.119288 0.858037 +vn 0.862116 0.112906 0.493972 +vn 0.864783 0.062737 0.498211 +vn 0.522059 0.054243 0.851183 +vn 0.559013 0.035015 0.828420 +vn 0.998507 0.054619 0.000000 +vn 0.998889 0.047128 -0.000794 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.848748 -0.198912 0.489960 +vn 0.915190 -0.136671 0.379143 +vn 0.970776 0.085464 0.224254 +vn 0.946638 -0.198907 0.253600 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.753817 -0.625309 0.201863 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.773684 -0.625316 0.101943 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.199709 -0.979855 0.000026 +vn 0.780383 -0.625302 0.000016 +vn 0.834536 -0.548215 0.054865 +vn -0.079997 -0.996795 -0.000012 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn 0.199250 -0.979861 0.013125 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.753817 -0.625309 0.201863 +vn 0.197953 -0.979864 0.026106 +vn 0.773684 -0.625316 0.101943 +vn 0.820199 -0.548350 0.163050 +vn -0.079314 -0.996795 -0.010461 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn 0.195829 -0.979864 0.038953 +vn 0.192889 -0.979859 0.051676 +vn 0.848748 -0.198912 0.489960 +vn 0.675878 -0.625313 0.390093 +vn 0.749973 -0.548375 0.369898 +vn 0.915190 -0.136671 0.379143 +vn 0.720908 -0.625314 0.298787 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.192889 -0.979859 0.051676 +vn 0.753817 -0.625309 0.201863 +vn 0.792045 -0.548040 0.268918 +vn -0.077272 -0.996795 -0.020703 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn 0.189096 -0.979856 0.064228 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.675878 -0.625313 0.390093 +vn 0.184454 -0.979861 0.076474 +vn 0.720908 -0.625314 0.298787 +vn 0.749973 -0.548375 0.369898 +vn -0.073898 -0.996795 -0.030640 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn 0.179057 -0.979865 0.088341 +vn 0.172924 -0.979863 0.099831 +vn 0.559013 0.035015 0.828420 +vn 0.489963 -0.198913 0.848746 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.692977 -0.198918 0.692975 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.551796 -0.625317 0.551816 +vn 0.628648 -0.548296 0.551520 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.619062 -0.625306 0.475137 +vn 0.172924 -0.979863 0.099831 +vn 0.675878 -0.625313 0.390093 +vn 0.695502 -0.548117 0.464591 +vn -0.069281 -0.996795 -0.039999 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn 0.166042 -0.979858 0.110944 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.551796 -0.625317 0.551816 +vn 0.158405 -0.979857 0.121607 +vn 0.619062 -0.625306 0.475137 +vn 0.628648 -0.548296 0.551520 +vn -0.063454 -0.996795 -0.048715 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn 0.150082 -0.979862 0.131702 +vn 0.141165 -0.979865 0.141202 +vn 0.489963 -0.198913 0.848746 +vn 0.390067 -0.625315 0.675892 +vn 0.464580 -0.548113 0.695513 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.475115 -0.625305 0.619080 +vn 0.141165 -0.979865 0.141202 +vn 0.551796 -0.625317 0.551816 +vn 0.551508 -0.548294 0.628659 +vn -0.056560 -0.996795 -0.056577 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn 0.131662 -0.979863 0.150115 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.390067 -0.625315 0.675892 +vn 0.121566 -0.979857 0.158438 +vn 0.475115 -0.625305 0.619080 +vn 0.464580 -0.548113 0.695513 +vn -0.048696 -0.996795 -0.063468 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn 0.110900 -0.979858 0.166071 +vn 0.099785 -0.979863 0.172949 +vn 0.862907 0.102956 0.494765 +vn 0.499945 0.102956 0.859916 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.994681 0.102958 -0.002990 +vn 0.862907 0.102956 0.494765 +vn 0.998889 0.047128 -0.000794 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.863780 0.089908 0.495782 +vn 0.500192 0.089907 0.861234 +vn 0.993600 0.112908 -0.003282 +vn 0.992853 0.119290 -0.003582 +vn 0.861619 0.119288 0.493338 +vn 0.994681 0.102958 -0.002990 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.862116 0.112906 0.493972 +vn 0.499657 0.112906 0.858834 +vn -0.972486 0.075824 0.220276 +vn -0.865986 0.007573 0.500011 +vn -0.863839 0.062737 0.499846 +vn 0.000000 0.054620 0.998507 +vn 0.000794 0.047128 0.998889 +vn -0.520588 0.054246 0.852083 +vn 0.522059 0.054243 0.851183 +vn 0.000794 0.047128 0.998889 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn 0.000000 -0.198908 0.980018 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.253603 -0.198906 0.946637 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.201834 -0.625309 0.753825 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.298761 -0.625313 0.720920 +vn 0.099785 -0.979863 0.172949 +vn 0.390067 -0.625315 0.675892 +vn 0.369884 -0.548374 0.749982 +vn -0.039978 -0.996795 -0.069293 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn 0.088294 -0.979865 0.179080 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.201834 -0.625309 0.753825 +vn 0.076426 -0.979861 0.184474 +vn 0.298761 -0.625313 0.720920 +vn 0.268901 -0.548039 0.792052 +vn -0.030617 -0.996795 -0.073907 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn 0.064178 -0.979856 0.189113 +vn 0.051625 -0.979859 0.192902 +vn 0.000000 -0.198908 0.980018 +vn -0.000016 -0.625302 0.780383 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.101911 -0.625316 0.773688 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.051625 -0.979859 0.192902 +vn 0.201834 -0.625309 0.753825 +vn 0.163032 -0.548348 0.820204 +vn -0.020680 -0.996795 -0.077279 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn 0.038902 -0.979864 0.195841 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn -0.000016 -0.625302 0.780383 +vn 0.026053 -0.979864 0.197959 +vn 0.101911 -0.625316 0.773688 +vn 0.054845 -0.548214 0.834538 +vn -0.010437 -0.996795 -0.079315 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn 0.013072 -0.979860 0.199255 +vn -0.000027 -0.979855 0.199708 +vn -0.559013 0.035015 0.828420 +vn -0.489963 -0.198913 0.848746 +vn -0.379146 -0.136670 0.915188 +vn -0.224256 0.085466 0.970775 +vn -0.253603 -0.198906 0.946637 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.201864 -0.625309 0.753817 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.101942 -0.625316 0.773684 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.000027 -0.979855 0.199708 +vn -0.000016 -0.625302 0.780383 +vn -0.054866 -0.548214 0.834537 +vn 0.000012 -0.996795 -0.079997 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn -0.013125 -0.979860 0.199252 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.201864 -0.625309 0.753817 +vn -0.026105 -0.979864 0.197952 +vn -0.101942 -0.625316 0.773684 +vn -0.163052 -0.548348 0.820200 +vn 0.010461 -0.996795 -0.079312 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn -0.038954 -0.979864 0.195830 +vn -0.051676 -0.979859 0.192887 +vn -0.489963 -0.198913 0.848746 +vn -0.390094 -0.625314 0.675876 +vn -0.369902 -0.548374 0.749972 +vn -0.379146 -0.136670 0.915188 +vn -0.298790 -0.625312 0.720908 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.051676 -0.979859 0.192887 +vn -0.201864 -0.625309 0.753817 +vn -0.268920 -0.548039 0.792045 +vn 0.020704 -0.996795 -0.077272 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn -0.064229 -0.979856 0.189096 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.390094 -0.625314 0.675876 +vn -0.076475 -0.979861 0.184454 +vn -0.298790 -0.625312 0.720908 +vn -0.369902 -0.548374 0.749972 +vn 0.030640 -0.996795 -0.073898 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn -0.088341 -0.979865 0.179057 +vn -0.099830 -0.979863 0.172922 +vn -0.559013 0.035015 0.828420 +vn -0.520588 0.054246 0.852083 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.848748 -0.198912 0.489960 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.692977 -0.198918 0.692975 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551819 -0.625315 0.551794 +vn -0.551523 -0.548295 0.628645 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.475140 -0.625305 0.619061 +vn -0.099830 -0.979863 0.172922 +vn -0.390094 -0.625314 0.675876 +vn -0.464597 -0.548113 0.695501 +vn 0.039999 -0.996795 -0.069281 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn -0.110944 -0.979858 0.166042 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.551819 -0.625315 0.551794 +vn -0.121608 -0.979857 0.158406 +vn -0.475140 -0.625305 0.619061 +vn -0.551523 -0.548295 0.628645 +vn 0.048715 -0.996795 -0.063453 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn -0.131702 -0.979863 0.150080 +vn -0.141203 -0.979865 0.141164 +vn -0.848748 -0.198912 0.489960 +vn -0.675893 -0.625315 0.390065 +vn -0.695513 -0.548117 0.464574 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.619082 -0.625304 0.475112 +vn -0.141203 -0.979865 0.141164 +vn -0.551819 -0.625315 0.551794 +vn -0.628661 -0.548296 0.551504 +vn 0.056577 -0.996795 -0.056559 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn -0.150116 -0.979863 0.131661 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.675893 -0.625315 0.390065 +vn -0.158439 -0.979857 0.121565 +vn -0.619082 -0.625304 0.475112 +vn -0.695513 -0.548117 0.464574 +vn 0.063469 -0.996795 -0.048696 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn -0.166073 -0.979858 0.110900 +vn -0.172949 -0.979863 0.099784 +vn -0.959759 -0.214953 0.180714 +vn -0.972486 0.075824 0.220276 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.787262 -0.610234 0.088501 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.720921 -0.625312 0.298759 +vn -0.172949 -0.979863 0.099784 +vn -0.675893 -0.625315 0.390065 +vn -0.749983 -0.548375 0.369880 +vn 0.069293 -0.996795 -0.039977 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn -0.179081 -0.979865 0.088293 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.787262 -0.610234 0.088501 +vn -0.184475 -0.979861 0.076425 +vn -0.720921 -0.625312 0.298759 +vn -0.792052 -0.548040 0.268898 +vn 0.073908 -0.996795 -0.030617 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn -0.189113 -0.979856 0.064178 +vn -0.217514 -0.975719 0.025702 +vn -0.059975 -0.994232 0.088919 +vn 0.079340 -0.996763 -0.012975 +vn -0.217514 -0.975719 0.025702 +vn 0.003582 0.119290 0.992853 +vn -0.493340 0.119288 0.861618 +vn 0.003282 0.112908 0.993600 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn -0.494767 0.102956 0.862905 +vn 0.500192 0.089907 0.861234 +vn 0.499945 0.102956 0.859916 +vn 0.002990 0.102958 0.994681 +vn 0.522059 0.054243 0.851183 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.002546 0.089909 0.995947 +vn -0.495785 0.089908 0.863779 +vn 0.499657 0.112906 0.858834 +vn 0.499543 0.119288 0.858037 +vn 0.003582 0.119290 0.992853 +vn 0.499945 0.102956 0.859916 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.003282 0.112908 0.993600 +vn -0.493974 0.112906 0.862115 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.994681 0.102958 0.002990 +vn -0.495785 0.089908 0.863779 +vn -0.494767 0.102956 0.862905 +vn -0.859917 0.102956 0.499943 +vn -0.520588 0.054246 0.852083 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.861235 0.089907 0.500190 +vn -0.995947 0.089909 0.002546 +vn -0.493974 0.112906 0.862115 +vn -0.493340 0.119288 0.861618 +vn -0.858038 0.119288 0.499541 +vn -0.494767 0.102956 0.862905 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.858835 0.112906 0.499655 +vn -0.993600 0.112908 0.003282 +vn 0.860140 0.138592 0.490867 +vn 0.499499 0.138592 0.855157 +vn 0.860102 0.137445 0.491258 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.499366 0.128646 0.856787 +vn 0.992193 0.124653 -0.003810 +vn 0.991682 0.128649 -0.004054 +vn 0.860841 0.128646 0.492344 +vn 0.992853 0.119290 -0.003582 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.861162 0.124651 0.492811 +vn 0.499410 0.124651 0.857352 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.499299 0.134937 0.855858 +vn 0.991220 0.132159 -0.004236 +vn 0.990844 0.134939 -0.004460 +vn 0.860318 0.134936 0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.860531 0.132157 0.491956 +vn 0.499292 0.132157 0.856295 +vn 0.990337 0.138595 -0.004983 +vn 0.860140 0.138592 0.490867 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.860102 0.137445 0.491258 +vn 0.499269 0.137445 0.855476 +vn -0.857353 0.124650 0.499408 +vn -0.856788 0.128646 0.499364 +vn -0.991682 0.128649 0.004054 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn -0.492346 0.128646 0.860840 +vn 0.499410 0.124651 0.857352 +vn 0.499366 0.128646 0.856787 +vn 0.004054 0.128649 0.991682 +vn 0.499543 0.119288 0.858037 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.003810 0.124653 0.992193 +vn -0.492814 0.124651 0.861160 +vn -0.492814 0.124651 0.861160 +vn -0.492346 0.128646 0.860840 +vn -0.856788 0.128646 0.499364 +vn -0.493340 0.119288 0.861618 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.857353 0.124650 0.499408 +vn -0.992193 0.124653 0.003810 +vn 0.004983 0.138595 0.990337 +vn -0.490869 0.138592 0.860139 +vn 0.004625 0.137448 0.990498 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn -0.491576 0.134936 0.860317 +vn 0.499292 0.132157 0.856295 +vn 0.499299 0.134937 0.855858 +vn 0.004460 0.134939 0.990844 +vn 0.499366 0.128646 0.856787 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.004236 0.132159 0.991220 +vn -0.491957 0.132157 0.860530 +vn 0.499499 0.138592 0.855157 +vn 0.004983 0.138595 0.990337 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.004625 0.137448 0.990498 +vn -0.491260 0.137445 0.860100 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.990844 0.134939 0.004460 +vn -0.491957 0.132157 0.860530 +vn -0.491576 0.134936 0.860317 +vn -0.855859 0.134936 0.499297 +vn -0.492346 0.128646 0.860840 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.856296 0.132157 0.499291 +vn -0.991220 0.132159 0.004236 +vn -0.490869 0.138592 0.860139 +vn -0.855158 0.138592 0.499497 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.855477 0.137445 0.499267 +vn -0.990498 0.137448 0.004625 +vn -0.990337 0.138595 0.004983 +vn -0.990498 0.137448 0.004625 +vn -0.855477 0.137445 0.499267 +vn 0.990337 0.138595 -0.004983 +vn 0.990498 0.137448 -0.004625 +vn 0.855477 0.137445 -0.499267 +vn 0.992853 0.119290 -0.003582 +vn 0.993600 0.112908 -0.003282 +vn 0.858835 0.112906 -0.499655 +vn -0.499543 0.119288 -0.858037 +vn -0.499657 0.112906 -0.858834 +vn -0.862116 0.112906 -0.493972 +vn -0.679581 0.085468 -0.728605 +vn -0.865986 0.007573 -0.500011 +vn -0.864783 0.062737 -0.498211 +vn -0.864783 0.062737 -0.498211 +vn -0.559013 0.035015 -0.828420 +vn -0.679581 0.085468 -0.728605 +vn -0.864783 0.062737 -0.498211 +vn -0.865986 0.007573 -0.500011 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.998818 0.048476 0.003588 +vn -0.864783 0.062737 -0.498211 +vn -0.915190 -0.136671 -0.379143 +vn -0.946638 -0.198907 -0.253600 +vn -0.970776 0.085464 -0.224254 +vn -0.970776 0.085464 -0.224254 +vn -0.865986 0.007573 -0.500011 +vn -0.915190 -0.136671 -0.379143 +vn -0.982121 -0.136787 -0.129332 +vn -0.974045 -0.216081 0.067421 +vn -0.998818 0.048476 0.003588 +vn -0.998818 0.048476 0.003588 +vn -0.970776 0.085464 -0.224254 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.773684 -0.625316 -0.101943 +vn -0.982121 -0.136787 -0.129332 +vn -0.820199 -0.548350 -0.163050 +vn -0.982121 -0.136787 -0.129332 +vn -0.946638 -0.198907 -0.253600 +vn -0.834536 -0.548214 -0.054865 +vn -0.774567 -0.626221 0.088845 +vn -0.974045 -0.216081 0.067421 +vn -0.974045 -0.216081 0.067421 +vn -0.982121 -0.136787 -0.129332 +vn -0.834536 -0.548214 -0.054865 +vn -0.773684 -0.625316 -0.101943 +vn -0.197953 -0.979864 -0.026106 +vn -0.199250 -0.979861 -0.013125 +vn -0.834536 -0.548214 -0.054865 +vn -0.199250 -0.979861 -0.013125 +vn -0.195626 -0.976106 0.094593 +vn -0.199250 -0.979861 -0.013125 +vn 0.079824 -0.996795 0.005260 +vn -0.059975 -0.994232 0.088919 +vn -0.197953 -0.979864 -0.026106 +vn 0.079314 -0.996795 0.010461 +vn 0.079824 -0.996795 0.005260 +vn -0.753817 -0.625309 -0.201863 +vn -0.192889 -0.979859 -0.051676 +vn -0.195829 -0.979864 -0.038953 +vn -0.820199 -0.548350 -0.163050 +vn -0.195829 -0.979864 -0.038953 +vn -0.197953 -0.979864 -0.026106 +vn -0.195829 -0.979864 -0.038953 +vn 0.078460 -0.996795 0.015609 +vn 0.079314 -0.996795 0.010461 +vn -0.192889 -0.979859 -0.051676 +vn 0.077272 -0.996795 0.020703 +vn 0.078460 -0.996795 0.015609 +vn -0.749973 -0.548375 -0.369898 +vn -0.720908 -0.625314 -0.298787 +vn -0.915190 -0.136671 -0.379143 +vn -0.915190 -0.136671 -0.379143 +vn -0.848748 -0.198912 -0.489960 +vn -0.749973 -0.548375 -0.369898 +vn -0.792045 -0.548040 -0.268918 +vn -0.753817 -0.625309 -0.201863 +vn -0.946638 -0.198907 -0.253600 +vn -0.946638 -0.198907 -0.253600 +vn -0.915190 -0.136671 -0.379143 +vn -0.792045 -0.548040 -0.268918 +vn -0.720908 -0.625314 -0.298787 +vn -0.184454 -0.979861 -0.076474 +vn -0.189096 -0.979856 -0.064228 +vn -0.792045 -0.548040 -0.268918 +vn -0.189096 -0.979856 -0.064228 +vn -0.192889 -0.979859 -0.051676 +vn -0.189096 -0.979856 -0.064228 +vn 0.075746 -0.996795 0.025730 +vn 0.077272 -0.996795 0.020703 +vn -0.184454 -0.979861 -0.076474 +vn 0.073898 -0.996795 0.030640 +vn 0.075746 -0.996795 0.025730 +vn -0.675878 -0.625313 -0.390093 +vn -0.172924 -0.979863 -0.099831 +vn -0.179057 -0.979865 -0.088341 +vn -0.749973 -0.548375 -0.369898 +vn -0.179057 -0.979865 -0.088341 +vn -0.184454 -0.979861 -0.076474 +vn -0.179057 -0.979865 -0.088341 +vn 0.071742 -0.996795 0.035397 +vn 0.073898 -0.996795 0.030640 +vn -0.172924 -0.979863 -0.099831 +vn 0.069281 -0.996795 0.039999 +vn 0.071742 -0.996795 0.035397 +vn -0.559013 0.035015 -0.828420 +vn -0.489963 -0.198913 -0.848746 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.679581 0.085468 -0.728605 +vn -0.559013 0.035015 -0.828420 +vn -0.785908 -0.136554 -0.603077 +vn -0.848748 -0.198912 -0.489960 +vn -0.865986 0.007573 -0.500011 +vn -0.865986 0.007573 -0.500011 +vn -0.679581 0.085468 -0.728605 +vn -0.785908 -0.136554 -0.603077 +vn -0.628648 -0.548296 -0.551520 +vn -0.619062 -0.625306 -0.475137 +vn -0.785908 -0.136554 -0.603077 +vn -0.785908 -0.136554 -0.603077 +vn -0.692977 -0.198918 -0.692975 +vn -0.628648 -0.548296 -0.551520 +vn -0.695502 -0.548117 -0.464591 +vn -0.675878 -0.625313 -0.390093 +vn -0.848748 -0.198912 -0.489960 +vn -0.695502 -0.548117 -0.464591 +vn -0.848748 -0.198912 -0.489960 +vn -0.785908 -0.136554 -0.603077 +vn -0.619062 -0.625306 -0.475137 +vn -0.158405 -0.979857 -0.121607 +vn -0.166042 -0.979858 -0.110944 +vn -0.695502 -0.548117 -0.464591 +vn -0.166042 -0.979858 -0.110944 +vn -0.172924 -0.979863 -0.099831 +vn -0.166042 -0.979858 -0.110944 +vn 0.066515 -0.996795 0.044445 +vn 0.069281 -0.996795 0.039999 +vn -0.158405 -0.979857 -0.121607 +vn 0.063454 -0.996795 0.048715 +vn 0.066515 -0.996795 0.044445 +vn -0.551796 -0.625317 -0.551816 +vn -0.141165 -0.979865 -0.141202 +vn -0.150082 -0.979862 -0.131702 +vn -0.628648 -0.548296 -0.551520 +vn -0.150082 -0.979862 -0.131702 +vn -0.158405 -0.979857 -0.121607 +vn -0.150082 -0.979862 -0.131702 +vn 0.060129 -0.996795 0.052767 +vn 0.063454 -0.996795 0.048715 +vn -0.141165 -0.979865 -0.141202 +vn 0.056560 -0.996795 0.056577 +vn 0.060129 -0.996795 0.052767 +vn -0.464580 -0.548113 -0.695513 +vn -0.475115 -0.625305 -0.619080 +vn -0.603081 -0.136554 -0.785905 +vn -0.603081 -0.136554 -0.785905 +vn -0.489963 -0.198913 -0.848746 +vn -0.464580 -0.548113 -0.695513 +vn -0.551508 -0.548294 -0.628659 +vn -0.551796 -0.625317 -0.551816 +vn -0.692977 -0.198918 -0.692975 +vn -0.551508 -0.548294 -0.628659 +vn -0.692977 -0.198918 -0.692975 +vn -0.603081 -0.136554 -0.785905 +vn -0.475115 -0.625305 -0.619080 +vn -0.121566 -0.979857 -0.158438 +vn -0.131662 -0.979863 -0.150115 +vn -0.551508 -0.548294 -0.628659 +vn -0.131662 -0.979863 -0.150115 +vn -0.141165 -0.979865 -0.141202 +vn -0.131662 -0.979863 -0.150115 +vn 0.052748 -0.996795 0.060144 +vn 0.056560 -0.996795 0.056577 +vn -0.121566 -0.979857 -0.158438 +vn 0.048696 -0.996795 0.063468 +vn 0.052748 -0.996795 0.060144 +vn -0.390067 -0.625315 -0.675892 +vn -0.099785 -0.979863 -0.172949 +vn -0.110900 -0.979858 -0.166071 +vn -0.464580 -0.548113 -0.695513 +vn -0.110900 -0.979858 -0.166071 +vn -0.121566 -0.979857 -0.158438 +vn -0.110900 -0.979858 -0.166071 +vn 0.044424 -0.996795 0.066528 +vn 0.048696 -0.996795 0.063468 +vn -0.099785 -0.979863 -0.172949 +vn 0.039978 -0.996795 0.069293 +vn 0.044424 -0.996795 0.066528 +vn -0.499945 0.102956 -0.859916 +vn -0.500192 0.089907 -0.861234 +vn -0.863780 0.089908 -0.495782 +vn -0.862907 0.102956 -0.494765 +vn -0.863780 0.089908 -0.495782 +vn -0.995947 0.089909 0.002546 +vn -0.863780 0.089908 -0.495782 +vn -0.864783 0.062737 -0.498211 +vn -0.998889 0.047128 0.000794 +vn -0.500192 0.089907 -0.861234 +vn -0.522059 0.054243 -0.851183 +vn -0.864783 0.062737 -0.498211 +vn -0.861619 0.119288 -0.493338 +vn -0.862116 0.112906 -0.493972 +vn -0.993600 0.112908 0.003282 +vn -0.862116 0.112906 -0.493972 +vn -0.862907 0.102956 -0.494765 +vn -0.994681 0.102958 0.002990 +vn -0.499657 0.112906 -0.858834 +vn -0.499945 0.102956 -0.859916 +vn -0.862907 0.102956 -0.494765 +vn 0.863839 0.062737 -0.499846 +vn 0.998889 0.047128 -0.000794 +vn 0.998507 0.054619 0.000000 +vn 0.863839 0.062737 -0.499846 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 -0.224254 +vn 0.520588 0.054246 -0.852083 +vn 0.559013 0.035015 -0.828420 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn 0.520588 0.054246 -0.852083 +vn -0.224256 0.085466 -0.970775 +vn -0.559013 0.035015 -0.828420 +vn -0.522059 0.054243 -0.851183 +vn -0.522059 0.054243 -0.851183 +vn -0.000000 0.054620 -0.998507 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.253603 -0.198906 -0.946637 +vn -0.224256 0.085466 -0.970775 +vn -0.129333 -0.136787 -0.982121 +vn -0.224256 0.085466 -0.970775 +vn -0.000000 0.054620 -0.998507 +vn -0.379146 -0.136670 -0.915188 +vn -0.489963 -0.198913 -0.848746 +vn -0.559013 0.035015 -0.828420 +vn -0.379146 -0.136670 -0.915188 +vn -0.559013 0.035015 -0.828420 +vn -0.224256 0.085466 -0.970775 +vn -0.268901 -0.548039 -0.792052 +vn -0.298761 -0.625313 -0.720920 +vn -0.379146 -0.136670 -0.915188 +vn -0.268901 -0.548039 -0.792052 +vn -0.379146 -0.136670 -0.915188 +vn -0.253603 -0.198906 -0.946637 +vn -0.369884 -0.548374 -0.749982 +vn -0.390067 -0.625315 -0.675892 +vn -0.489963 -0.198913 -0.848746 +vn -0.369884 -0.548374 -0.749982 +vn -0.489963 -0.198913 -0.848746 +vn -0.379146 -0.136670 -0.915188 +vn -0.298761 -0.625313 -0.720920 +vn -0.076426 -0.979861 -0.184474 +vn -0.088294 -0.979865 -0.179080 +vn -0.369884 -0.548374 -0.749982 +vn -0.088294 -0.979865 -0.179080 +vn -0.099785 -0.979863 -0.172949 +vn -0.088294 -0.979865 -0.179080 +vn 0.035375 -0.996795 0.071753 +vn 0.039978 -0.996795 0.069293 +vn -0.076426 -0.979861 -0.184474 +vn 0.030617 -0.996795 0.073907 +vn 0.035375 -0.996795 0.071753 +vn -0.201834 -0.625309 -0.753825 +vn -0.051625 -0.979859 -0.192902 +vn -0.064178 -0.979856 -0.189113 +vn -0.268901 -0.548039 -0.792052 +vn -0.064178 -0.979856 -0.189113 +vn -0.076426 -0.979861 -0.184474 +vn -0.064178 -0.979856 -0.189113 +vn 0.025707 -0.996795 0.075754 +vn 0.030617 -0.996795 0.073907 +vn -0.051625 -0.979859 -0.192902 +vn 0.020680 -0.996795 0.077279 +vn 0.025707 -0.996795 0.075754 +vn -0.054845 -0.548214 -0.834538 +vn -0.101911 -0.625316 -0.773688 +vn -0.129333 -0.136787 -0.982121 +vn -0.054845 -0.548214 -0.834538 +vn -0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.163032 -0.548348 -0.820204 +vn -0.201834 -0.625309 -0.753825 +vn -0.253603 -0.198906 -0.946637 +vn -0.253603 -0.198906 -0.946637 +vn -0.129333 -0.136787 -0.982121 +vn -0.163032 -0.548348 -0.820204 +vn -0.101911 -0.625316 -0.773688 +vn -0.026053 -0.979864 -0.197959 +vn -0.038902 -0.979864 -0.195841 +vn -0.163032 -0.548348 -0.820204 +vn -0.038902 -0.979864 -0.195841 +vn -0.051625 -0.979859 -0.192902 +vn -0.038902 -0.979864 -0.195841 +vn 0.015585 -0.996795 0.078466 +vn 0.020680 -0.996795 0.077279 +vn -0.026053 -0.979864 -0.197959 +vn 0.010437 -0.996795 0.079315 +vn 0.015585 -0.996795 0.078466 +vn 0.000016 -0.625302 -0.780383 +vn 0.000027 -0.979855 -0.199708 +vn -0.013072 -0.979860 -0.199255 +vn -0.054845 -0.548214 -0.834538 +vn -0.013072 -0.979860 -0.199255 +vn -0.026053 -0.979864 -0.197959 +vn -0.013072 -0.979860 -0.199255 +vn 0.005235 -0.996795 0.079826 +vn 0.010437 -0.996795 0.079315 +vn 0.000027 -0.979855 -0.199708 +vn -0.000012 -0.996795 0.079997 +vn 0.005235 -0.996795 0.079826 +vn 0.379146 -0.136670 -0.915188 +vn 0.253603 -0.198906 -0.946637 +vn 0.224256 0.085466 -0.970775 +vn 0.224256 0.085466 -0.970775 +vn 0.559013 0.035015 -0.828420 +vn 0.379146 -0.136670 -0.915188 +vn 0.129333 -0.136787 -0.982121 +vn 0.000000 -0.198908 -0.980018 +vn -0.000000 0.054620 -0.998507 +vn -0.000000 0.054620 -0.998507 +vn 0.224256 0.085466 -0.970775 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.101942 -0.625316 -0.773684 +vn 0.129333 -0.136787 -0.982121 +vn 0.163052 -0.548348 -0.820200 +vn 0.129333 -0.136787 -0.982121 +vn 0.253603 -0.198906 -0.946637 +vn 0.054866 -0.548214 -0.834537 +vn 0.000016 -0.625302 -0.780383 +vn 0.000000 -0.198908 -0.980018 +vn 0.000000 -0.198908 -0.980018 +vn 0.129333 -0.136787 -0.982121 +vn 0.054866 -0.548214 -0.834537 +vn 0.101942 -0.625316 -0.773684 +vn 0.026105 -0.979864 -0.197952 +vn 0.013125 -0.979860 -0.199252 +vn 0.054866 -0.548214 -0.834537 +vn 0.013125 -0.979860 -0.199252 +vn 0.000027 -0.979855 -0.199708 +vn 0.013125 -0.979860 -0.199252 +vn -0.005260 -0.996795 0.079825 +vn -0.000012 -0.996795 0.079997 +vn 0.026105 -0.979864 -0.197952 +vn -0.010461 -0.996795 0.079312 +vn -0.005260 -0.996795 0.079825 +vn 0.201864 -0.625309 -0.753817 +vn 0.051676 -0.979859 -0.192887 +vn 0.038954 -0.979864 -0.195830 +vn 0.163052 -0.548348 -0.820200 +vn 0.038954 -0.979864 -0.195830 +vn 0.026105 -0.979864 -0.197952 +vn 0.038954 -0.979864 -0.195830 +vn -0.015609 -0.996795 0.078461 +vn -0.010461 -0.996795 0.079312 +vn 0.051676 -0.979859 -0.192887 +vn -0.020704 -0.996795 0.077272 +vn -0.015609 -0.996795 0.078461 +vn 0.369902 -0.548374 -0.749972 +vn 0.298790 -0.625312 -0.720908 +vn 0.379146 -0.136670 -0.915188 +vn 0.379146 -0.136670 -0.915188 +vn 0.489963 -0.198913 -0.848746 +vn 0.369902 -0.548374 -0.749972 +vn 0.268920 -0.548039 -0.792045 +vn 0.201864 -0.625309 -0.753817 +vn 0.253603 -0.198906 -0.946637 +vn 0.253603 -0.198906 -0.946637 +vn 0.379146 -0.136670 -0.915188 +vn 0.268920 -0.548039 -0.792045 +vn 0.298790 -0.625312 -0.720908 +vn 0.076475 -0.979861 -0.184454 +vn 0.064229 -0.979856 -0.189096 +vn 0.268920 -0.548039 -0.792045 +vn 0.064229 -0.979856 -0.189096 +vn 0.051676 -0.979859 -0.192887 +vn 0.064229 -0.979856 -0.189096 +vn -0.025730 -0.996795 0.075746 +vn -0.020704 -0.996795 0.077272 +vn 0.076475 -0.979861 -0.184454 +vn -0.030640 -0.996795 0.073898 +vn -0.025730 -0.996795 0.075746 +vn 0.390094 -0.625314 -0.675876 +vn 0.099830 -0.979863 -0.172922 +vn 0.088341 -0.979865 -0.179057 +vn 0.369902 -0.548374 -0.749972 +vn 0.088341 -0.979865 -0.179057 +vn 0.076475 -0.979861 -0.184454 +vn 0.088341 -0.979865 -0.179057 +vn -0.035397 -0.996795 0.071742 +vn -0.030640 -0.996795 0.073898 +vn 0.099830 -0.979863 -0.172922 +vn -0.039999 -0.996795 0.069281 +vn -0.035397 -0.996795 0.071742 +vn 0.863839 0.062737 -0.499846 +vn 0.865986 0.007573 -0.500011 +vn 0.679581 0.085468 -0.728605 +vn 0.679581 0.085468 -0.728605 +vn 0.559013 0.035015 -0.828420 +vn 0.863839 0.062737 -0.499846 +vn 0.785908 -0.136554 -0.603077 +vn 0.692977 -0.198918 -0.692975 +vn 0.679581 0.085468 -0.728605 +vn 0.785908 -0.136554 -0.603077 +vn 0.679581 0.085468 -0.728605 +vn 0.865986 0.007573 -0.500011 +vn 0.603081 -0.136554 -0.785905 +vn 0.489963 -0.198913 -0.848746 +vn 0.559013 0.035015 -0.828420 +vn 0.559013 0.035015 -0.828420 +vn 0.679581 0.085468 -0.728605 +vn 0.603081 -0.136554 -0.785905 +vn 0.551523 -0.548295 -0.628645 +vn 0.475140 -0.625305 -0.619061 +vn 0.603081 -0.136554 -0.785905 +vn 0.603081 -0.136554 -0.785905 +vn 0.692977 -0.198918 -0.692975 +vn 0.551523 -0.548295 -0.628645 +vn 0.464597 -0.548113 -0.695501 +vn 0.390094 -0.625314 -0.675876 +vn 0.489963 -0.198913 -0.848746 +vn 0.464597 -0.548113 -0.695501 +vn 0.489963 -0.198913 -0.848746 +vn 0.603081 -0.136554 -0.785905 +vn 0.475140 -0.625305 -0.619061 +vn 0.121608 -0.979857 -0.158406 +vn 0.110944 -0.979858 -0.166042 +vn 0.464597 -0.548113 -0.695501 +vn 0.110944 -0.979858 -0.166042 +vn 0.099830 -0.979863 -0.172922 +vn 0.110944 -0.979858 -0.166042 +vn -0.044445 -0.996795 0.066514 +vn -0.039999 -0.996795 0.069281 +vn 0.121608 -0.979857 -0.158406 +vn -0.048715 -0.996795 0.063453 +vn -0.044445 -0.996795 0.066514 +vn 0.551819 -0.625315 -0.551794 +vn 0.141203 -0.979865 -0.141164 +vn 0.131702 -0.979863 -0.150080 +vn 0.551523 -0.548295 -0.628645 +vn 0.131702 -0.979863 -0.150080 +vn 0.121608 -0.979857 -0.158406 +vn 0.131702 -0.979863 -0.150080 +vn -0.052767 -0.996795 0.060128 +vn -0.048715 -0.996795 0.063453 +vn 0.141203 -0.979865 -0.141164 +vn -0.056577 -0.996795 0.056559 +vn -0.052767 -0.996795 0.060128 +vn 0.695513 -0.548117 -0.464574 +vn 0.619082 -0.625304 -0.475112 +vn 0.785908 -0.136554 -0.603077 +vn 0.785908 -0.136554 -0.603077 +vn 0.848748 -0.198912 -0.489960 +vn 0.695513 -0.548117 -0.464574 +vn 0.628661 -0.548296 -0.551504 +vn 0.551819 -0.625315 -0.551794 +vn 0.692977 -0.198918 -0.692975 +vn 0.628661 -0.548296 -0.551504 +vn 0.692977 -0.198918 -0.692975 +vn 0.785908 -0.136554 -0.603077 +vn 0.619082 -0.625304 -0.475112 +vn 0.158439 -0.979857 -0.121565 +vn 0.150116 -0.979863 -0.131661 +vn 0.628661 -0.548296 -0.551504 +vn 0.150116 -0.979863 -0.131661 +vn 0.141203 -0.979865 -0.141164 +vn 0.150116 -0.979863 -0.131661 +vn -0.060145 -0.996795 0.052748 +vn -0.056577 -0.996795 0.056559 +vn 0.158439 -0.979857 -0.121565 +vn -0.063469 -0.996795 0.048696 +vn -0.060145 -0.996795 0.052748 +vn 0.675893 -0.625315 -0.390065 +vn 0.172949 -0.979863 -0.099784 +vn 0.166073 -0.979858 -0.110900 +vn 0.695513 -0.548117 -0.464574 +vn 0.166073 -0.979858 -0.110900 +vn 0.158439 -0.979857 -0.121565 +vn 0.166073 -0.979858 -0.110900 +vn -0.066529 -0.996795 0.044425 +vn -0.063469 -0.996795 0.048696 +vn 0.172949 -0.979863 -0.099784 +vn -0.069293 -0.996795 0.039977 +vn -0.066529 -0.996795 0.044425 +vn 0.998507 0.054619 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 -0.129332 +vn 0.982121 -0.136787 -0.129332 +vn 0.970776 0.085464 -0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.915190 -0.136671 -0.379143 +vn 0.848748 -0.198912 -0.489960 +vn 0.865986 0.007573 -0.500011 +vn 0.915190 -0.136671 -0.379143 +vn 0.865986 0.007573 -0.500011 +vn 0.970776 0.085464 -0.224254 +vn 0.792052 -0.548040 -0.268898 +vn 0.720921 -0.625312 -0.298759 +vn 0.915190 -0.136671 -0.379143 +vn 0.792052 -0.548040 -0.268898 +vn 0.915190 -0.136671 -0.379143 +vn 0.946638 -0.198907 -0.253600 +vn 0.749983 -0.548375 -0.369880 +vn 0.675893 -0.625315 -0.390065 +vn 0.848748 -0.198912 -0.489960 +vn 0.749983 -0.548375 -0.369880 +vn 0.848748 -0.198912 -0.489960 +vn 0.915190 -0.136671 -0.379143 +vn 0.720921 -0.625312 -0.298759 +vn 0.184475 -0.979861 -0.076425 +vn 0.179081 -0.979865 -0.088293 +vn 0.749983 -0.548375 -0.369880 +vn 0.179081 -0.979865 -0.088293 +vn 0.172949 -0.979863 -0.099784 +vn 0.179081 -0.979865 -0.088293 +vn -0.071753 -0.996795 0.035375 +vn -0.069293 -0.996795 0.039977 +vn 0.184475 -0.979861 -0.076425 +vn -0.073908 -0.996795 0.030617 +vn -0.071753 -0.996795 0.035375 +vn 0.753824 -0.625311 -0.201832 +vn 0.192902 -0.979859 -0.051624 +vn 0.189113 -0.979856 -0.064178 +vn 0.792052 -0.548040 -0.268898 +vn 0.189113 -0.979856 -0.064178 +vn 0.184475 -0.979861 -0.076425 +vn 0.189113 -0.979856 -0.064178 +vn -0.075754 -0.996795 0.025706 +vn -0.073908 -0.996795 0.030617 +vn 0.192902 -0.979859 -0.051624 +vn -0.077279 -0.996795 0.020680 +vn -0.075754 -0.996795 0.025706 +vn 0.980018 -0.198907 0.000000 +vn 0.780383 -0.625302 0.000016 +vn 0.834538 -0.548214 -0.054844 +vn 0.834538 -0.548214 -0.054844 +vn 0.982121 -0.136787 -0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.820204 -0.548349 -0.163030 +vn 0.753824 -0.625311 -0.201832 +vn 0.946638 -0.198907 -0.253600 +vn 0.946638 -0.198907 -0.253600 +vn 0.982121 -0.136787 -0.129332 +vn 0.820204 -0.548349 -0.163030 +vn 0.773688 -0.625316 -0.101912 +vn 0.197959 -0.979864 -0.026053 +vn 0.195842 -0.979864 -0.038902 +vn 0.820204 -0.548349 -0.163030 +vn 0.195842 -0.979864 -0.038902 +vn 0.192902 -0.979859 -0.051624 +vn 0.195842 -0.979864 -0.038902 +vn -0.078466 -0.996795 0.015585 +vn -0.077279 -0.996795 0.020680 +vn 0.197959 -0.979864 -0.026053 +vn -0.079316 -0.996795 0.010437 +vn -0.078466 -0.996795 0.015585 +vn 0.780383 -0.625302 0.000016 +vn 0.199709 -0.979855 0.000026 +vn 0.199256 -0.979860 -0.013072 +vn 0.834538 -0.548214 -0.054844 +vn 0.199256 -0.979860 -0.013072 +vn 0.197959 -0.979864 -0.026053 +vn 0.199256 -0.979860 -0.013072 +vn -0.079827 -0.996795 0.005235 +vn -0.079316 -0.996795 0.010437 +vn 0.199709 -0.979855 0.000026 +vn -0.079997 -0.996795 -0.000012 +vn -0.079827 -0.996795 0.005235 +vn 0.493340 0.119288 -0.861618 +vn 0.493974 0.112906 -0.862115 +vn -0.003282 0.112908 -0.993600 +vn 0.494767 0.102956 -0.862905 +vn 0.495785 0.089908 -0.863779 +vn -0.002546 0.089909 -0.995947 +vn -0.002990 0.102958 -0.994681 +vn -0.002546 0.089909 -0.995947 +vn -0.500192 0.089907 -0.861234 +vn -0.002546 0.089909 -0.995947 +vn -0.000794 0.047128 -0.998889 +vn -0.522059 0.054243 -0.851183 +vn 0.495785 0.089908 -0.863779 +vn 0.520588 0.054246 -0.852083 +vn -0.000794 0.047128 -0.998889 +vn -0.003582 0.119290 -0.992853 +vn -0.003282 0.112908 -0.993600 +vn -0.499657 0.112906 -0.858834 +vn -0.003282 0.112908 -0.993600 +vn -0.002990 0.102958 -0.994681 +vn -0.499945 0.102956 -0.859916 +vn 0.493974 0.112906 -0.862115 +vn 0.494767 0.102956 -0.862905 +vn -0.002990 0.102958 -0.994681 +vn 0.994681 0.102958 -0.002990 +vn 0.995947 0.089909 -0.002546 +vn 0.861235 0.089907 -0.500190 +vn 0.859917 0.102956 -0.499943 +vn 0.861235 0.089907 -0.500190 +vn 0.495785 0.089908 -0.863779 +vn 0.861235 0.089907 -0.500190 +vn 0.863839 0.062737 -0.499846 +vn 0.520588 0.054246 -0.852083 +vn 0.995947 0.089909 -0.002546 +vn 0.998889 0.047128 -0.000794 +vn 0.863839 0.062737 -0.499846 +vn 0.858038 0.119287 -0.499541 +vn 0.858835 0.112906 -0.499655 +vn 0.493974 0.112906 -0.862115 +vn 0.858835 0.112906 -0.499655 +vn 0.859917 0.102956 -0.499943 +vn 0.494767 0.102956 -0.862905 +vn 0.993600 0.112908 -0.003282 +vn 0.994681 0.102958 -0.002990 +vn 0.859917 0.102956 -0.499943 +vn -0.499499 0.138592 -0.855157 +vn -0.499269 0.137445 -0.855476 +vn -0.860102 0.137445 -0.491258 +vn -0.499366 0.128646 -0.856787 +vn -0.499410 0.124651 -0.857352 +vn -0.861162 0.124651 -0.492811 +vn -0.860841 0.128646 -0.492344 +vn -0.861162 0.124651 -0.492811 +vn -0.992193 0.124653 0.003810 +vn -0.861162 0.124651 -0.492811 +vn -0.861619 0.119288 -0.493338 +vn -0.992853 0.119290 0.003582 +vn -0.499410 0.124651 -0.857352 +vn -0.499543 0.119288 -0.858037 +vn -0.861619 0.119288 -0.493338 +vn -0.499299 0.134937 -0.855858 +vn -0.499292 0.132157 -0.856295 +vn -0.860532 0.132157 -0.491955 +vn -0.860318 0.134936 -0.491574 +vn -0.860532 0.132157 -0.491955 +vn -0.991220 0.132159 0.004236 +vn -0.860532 0.132157 -0.491955 +vn -0.860841 0.128646 -0.492344 +vn -0.991682 0.128649 0.004054 +vn -0.499292 0.132157 -0.856295 +vn -0.499366 0.128646 -0.856787 +vn -0.860841 0.128646 -0.492344 +vn -0.860140 0.138592 -0.490867 +vn -0.860102 0.137445 -0.491258 +vn -0.990498 0.137448 0.004625 +vn -0.860102 0.137445 -0.491258 +vn -0.860318 0.134936 -0.491574 +vn -0.990844 0.134939 0.004460 +vn -0.499269 0.137445 -0.855476 +vn -0.499299 0.134937 -0.855858 +vn -0.860318 0.134936 -0.491574 +vn 0.991682 0.128649 -0.004054 +vn 0.992193 0.124653 -0.003810 +vn 0.857353 0.124650 -0.499408 +vn 0.492346 0.128646 -0.860840 +vn 0.492814 0.124651 -0.861160 +vn -0.003810 0.124653 -0.992193 +vn -0.004054 0.128649 -0.991682 +vn -0.003810 0.124653 -0.992193 +vn -0.499410 0.124651 -0.857352 +vn -0.003810 0.124653 -0.992193 +vn -0.003582 0.119290 -0.992853 +vn -0.499543 0.119288 -0.858037 +vn 0.492814 0.124651 -0.861160 +vn 0.493340 0.119288 -0.861618 +vn -0.003582 0.119290 -0.992853 +vn 0.856788 0.128646 -0.499364 +vn 0.857353 0.124650 -0.499408 +vn 0.492814 0.124651 -0.861160 +vn 0.857353 0.124650 -0.499408 +vn 0.858038 0.119287 -0.499541 +vn 0.493340 0.119288 -0.861618 +vn 0.992193 0.124653 -0.003810 +vn 0.992853 0.119290 -0.003582 +vn 0.858038 0.119287 -0.499541 +vn 0.490869 0.138592 -0.860139 +vn 0.491260 0.137445 -0.860100 +vn -0.004625 0.137448 -0.990498 +vn 0.491576 0.134936 -0.860317 +vn 0.491957 0.132157 -0.860530 +vn -0.004236 0.132159 -0.991220 +vn -0.004460 0.134939 -0.990844 +vn -0.004236 0.132159 -0.991220 +vn -0.499292 0.132157 -0.856295 +vn -0.004236 0.132159 -0.991220 +vn -0.004054 0.128649 -0.991682 +vn -0.499366 0.128646 -0.856787 +vn 0.491957 0.132157 -0.860530 +vn 0.492346 0.128646 -0.860840 +vn -0.004054 0.128649 -0.991682 +vn -0.004983 0.138595 -0.990337 +vn -0.004625 0.137448 -0.990498 +vn -0.499269 0.137445 -0.855476 +vn -0.004625 0.137448 -0.990498 +vn -0.004460 0.134939 -0.990844 +vn -0.499299 0.134937 -0.855858 +vn 0.491260 0.137445 -0.860100 +vn 0.491576 0.134936 -0.860317 +vn -0.004460 0.134939 -0.990844 +vn 0.990844 0.134939 -0.004460 +vn 0.991220 0.132159 -0.004236 +vn 0.856296 0.132157 -0.499291 +vn 0.855859 0.134936 -0.499297 +vn 0.856296 0.132157 -0.499291 +vn 0.491957 0.132157 -0.860530 +vn 0.856296 0.132157 -0.499291 +vn 0.856788 0.128646 -0.499364 +vn 0.492346 0.128646 -0.860840 +vn 0.991220 0.132159 -0.004236 +vn 0.991682 0.128649 -0.004054 +vn 0.856788 0.128646 -0.499364 +vn 0.855158 0.138592 -0.499497 +vn 0.855477 0.137445 -0.499267 +vn 0.491260 0.137445 -0.860100 +vn 0.855477 0.137445 -0.499267 +vn 0.855859 0.134936 -0.499297 +vn 0.491576 0.134936 -0.860317 +vn 0.990498 0.137448 -0.004625 +vn 0.990844 0.134939 -0.004460 +vn 0.855859 0.134936 -0.499297 +vn -0.992853 0.119290 0.003582 +vn -0.993600 0.112908 0.003282 +vn -0.858835 0.112906 0.499655 +vn 0.499543 0.119288 0.858037 +vn 0.499657 0.112906 0.858834 +vn 0.862116 0.112906 0.493972 +vn 0.679581 0.085468 0.728605 +vn 0.865986 0.007573 0.500011 +vn 0.864783 0.062737 0.498211 +vn 0.864783 0.062737 0.498211 +vn 0.559013 0.035015 0.828420 +vn 0.679581 0.085468 0.728605 +vn 0.864783 0.062737 0.498211 +vn 0.865986 0.007573 0.500011 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.998507 0.054619 0.000000 +vn 0.864783 0.062737 0.498211 +vn 0.915190 -0.136671 0.379143 +vn 0.946638 -0.198907 0.253600 +vn 0.970776 0.085464 0.224254 +vn 0.970776 0.085464 0.224254 +vn 0.865986 0.007573 0.500011 +vn 0.915190 -0.136671 0.379143 +vn 0.982121 -0.136787 0.129332 +vn 0.980018 -0.198907 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.998507 0.054619 0.000000 +vn 0.970776 0.085464 0.224254 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.773684 -0.625316 0.101943 +vn 0.982121 -0.136787 0.129332 +vn 0.820199 -0.548350 0.163050 +vn 0.982121 -0.136787 0.129332 +vn 0.946638 -0.198907 0.253600 +vn 0.834536 -0.548215 0.054865 +vn 0.780383 -0.625302 0.000016 +vn 0.980018 -0.198907 0.000000 +vn 0.980018 -0.198907 0.000000 +vn 0.982121 -0.136787 0.129332 +vn 0.834536 -0.548215 0.054865 +vn 0.773684 -0.625316 0.101943 +vn 0.197953 -0.979864 0.026106 +vn 0.199250 -0.979861 0.013125 +vn 0.834536 -0.548215 0.054865 +vn 0.199250 -0.979861 0.013125 +vn 0.199709 -0.979855 0.000026 +vn 0.199250 -0.979861 0.013125 +vn -0.079824 -0.996795 -0.005260 +vn -0.079997 -0.996795 -0.000012 +vn 0.197953 -0.979864 0.026106 +vn -0.079314 -0.996795 -0.010461 +vn -0.079824 -0.996795 -0.005260 +vn 0.753817 -0.625309 0.201863 +vn 0.192889 -0.979859 0.051676 +vn 0.195829 -0.979864 0.038953 +vn 0.820199 -0.548350 0.163050 +vn 0.195829 -0.979864 0.038953 +vn 0.197953 -0.979864 0.026106 +vn 0.195829 -0.979864 0.038953 +vn -0.078460 -0.996795 -0.015609 +vn -0.079314 -0.996795 -0.010461 +vn 0.192889 -0.979859 0.051676 +vn -0.077272 -0.996795 -0.020703 +vn -0.078460 -0.996795 -0.015609 +vn 0.749973 -0.548375 0.369898 +vn 0.720908 -0.625314 0.298787 +vn 0.915190 -0.136671 0.379143 +vn 0.915190 -0.136671 0.379143 +vn 0.848748 -0.198912 0.489960 +vn 0.749973 -0.548375 0.369898 +vn 0.792045 -0.548040 0.268918 +vn 0.753817 -0.625309 0.201863 +vn 0.946638 -0.198907 0.253600 +vn 0.946638 -0.198907 0.253600 +vn 0.915190 -0.136671 0.379143 +vn 0.792045 -0.548040 0.268918 +vn 0.720908 -0.625314 0.298787 +vn 0.184454 -0.979861 0.076474 +vn 0.189096 -0.979856 0.064228 +vn 0.792045 -0.548040 0.268918 +vn 0.189096 -0.979856 0.064228 +vn 0.192889 -0.979859 0.051676 +vn 0.189096 -0.979856 0.064228 +vn -0.075746 -0.996795 -0.025730 +vn -0.077272 -0.996795 -0.020703 +vn 0.184454 -0.979861 0.076474 +vn -0.073898 -0.996795 -0.030640 +vn -0.075746 -0.996795 -0.025730 +vn 0.675878 -0.625313 0.390093 +vn 0.172924 -0.979863 0.099831 +vn 0.179057 -0.979865 0.088341 +vn 0.749973 -0.548375 0.369898 +vn 0.179057 -0.979865 0.088341 +vn 0.184454 -0.979861 0.076474 +vn 0.179057 -0.979865 0.088341 +vn -0.071742 -0.996795 -0.035397 +vn -0.073898 -0.996795 -0.030640 +vn 0.172924 -0.979863 0.099831 +vn -0.069281 -0.996795 -0.039999 +vn -0.071742 -0.996795 -0.035397 +vn 0.603081 -0.136554 0.785905 +vn 0.692977 -0.198918 0.692975 +vn 0.679581 0.085468 0.728605 +vn 0.603081 -0.136554 0.785905 +vn 0.679581 0.085468 0.728605 +vn 0.559013 0.035015 0.828420 +vn 0.785908 -0.136554 0.603077 +vn 0.848748 -0.198912 0.489960 +vn 0.865986 0.007573 0.500011 +vn 0.865986 0.007573 0.500011 +vn 0.679581 0.085468 0.728605 +vn 0.785908 -0.136554 0.603077 +vn 0.628648 -0.548296 0.551520 +vn 0.619062 -0.625306 0.475137 +vn 0.785908 -0.136554 0.603077 +vn 0.785908 -0.136554 0.603077 +vn 0.692977 -0.198918 0.692975 +vn 0.628648 -0.548296 0.551520 +vn 0.695502 -0.548117 0.464591 +vn 0.675878 -0.625313 0.390093 +vn 0.848748 -0.198912 0.489960 +vn 0.695502 -0.548117 0.464591 +vn 0.848748 -0.198912 0.489960 +vn 0.785908 -0.136554 0.603077 +vn 0.619062 -0.625306 0.475137 +vn 0.158405 -0.979857 0.121607 +vn 0.166042 -0.979858 0.110944 +vn 0.695502 -0.548117 0.464591 +vn 0.166042 -0.979858 0.110944 +vn 0.172924 -0.979863 0.099831 +vn 0.166042 -0.979858 0.110944 +vn -0.066515 -0.996795 -0.044445 +vn -0.069281 -0.996795 -0.039999 +vn 0.158405 -0.979857 0.121607 +vn -0.063454 -0.996795 -0.048715 +vn -0.066515 -0.996795 -0.044445 +vn 0.551796 -0.625317 0.551816 +vn 0.141165 -0.979865 0.141202 +vn 0.150082 -0.979862 0.131702 +vn 0.628648 -0.548296 0.551520 +vn 0.150082 -0.979862 0.131702 +vn 0.158405 -0.979857 0.121607 +vn 0.150082 -0.979862 0.131702 +vn -0.060129 -0.996795 -0.052767 +vn -0.063454 -0.996795 -0.048715 +vn 0.141165 -0.979865 0.141202 +vn -0.056560 -0.996795 -0.056577 +vn -0.060129 -0.996795 -0.052767 +vn 0.464580 -0.548113 0.695513 +vn 0.475115 -0.625305 0.619080 +vn 0.603081 -0.136554 0.785905 +vn 0.603081 -0.136554 0.785905 +vn 0.489963 -0.198913 0.848746 +vn 0.464580 -0.548113 0.695513 +vn 0.551508 -0.548294 0.628659 +vn 0.551796 -0.625317 0.551816 +vn 0.692977 -0.198918 0.692975 +vn 0.551508 -0.548294 0.628659 +vn 0.692977 -0.198918 0.692975 +vn 0.603081 -0.136554 0.785905 +vn 0.475115 -0.625305 0.619080 +vn 0.121566 -0.979857 0.158438 +vn 0.131662 -0.979863 0.150115 +vn 0.551508 -0.548294 0.628659 +vn 0.131662 -0.979863 0.150115 +vn 0.141165 -0.979865 0.141202 +vn 0.131662 -0.979863 0.150115 +vn -0.052748 -0.996795 -0.060144 +vn -0.056560 -0.996795 -0.056577 +vn 0.121566 -0.979857 0.158438 +vn -0.048696 -0.996795 -0.063468 +vn -0.052748 -0.996795 -0.060144 +vn 0.390067 -0.625315 0.675892 +vn 0.099785 -0.979863 0.172949 +vn 0.110900 -0.979858 0.166071 +vn 0.464580 -0.548113 0.695513 +vn 0.110900 -0.979858 0.166071 +vn 0.121566 -0.979857 0.158438 +vn 0.110900 -0.979858 0.166071 +vn -0.044424 -0.996795 -0.066528 +vn -0.048696 -0.996795 -0.063468 +vn 0.099785 -0.979863 0.172949 +vn -0.039978 -0.996795 -0.069293 +vn -0.044424 -0.996795 -0.066528 +vn 0.499945 0.102956 0.859916 +vn 0.500192 0.089907 0.861234 +vn 0.863780 0.089908 0.495782 +vn 0.862907 0.102956 0.494765 +vn 0.863780 0.089908 0.495782 +vn 0.995947 0.089909 -0.002546 +vn 0.863780 0.089908 0.495782 +vn 0.864783 0.062737 0.498211 +vn 0.998889 0.047128 -0.000794 +vn 0.500192 0.089907 0.861234 +vn 0.522059 0.054243 0.851183 +vn 0.864783 0.062737 0.498211 +vn 0.861619 0.119288 0.493338 +vn 0.862116 0.112906 0.493972 +vn 0.993600 0.112908 -0.003282 +vn 0.862116 0.112906 0.493972 +vn 0.862907 0.102956 0.494765 +vn 0.994681 0.102958 -0.002990 +vn 0.499657 0.112906 0.858834 +vn 0.499945 0.102956 0.859916 +vn 0.862907 0.102956 0.494765 +vn -0.863839 0.062737 0.499846 +vn -0.998889 0.047128 0.000794 +vn -0.998818 0.048476 0.003588 +vn -0.863839 0.062737 0.499846 +vn -0.998818 0.048476 0.003588 +vn -0.972486 0.075824 0.220276 +vn -0.520588 0.054246 0.852083 +vn -0.559013 0.035015 0.828420 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn -0.520588 0.054246 0.852083 +vn 0.224256 0.085466 0.970775 +vn 0.559013 0.035015 0.828420 +vn 0.522059 0.054243 0.851183 +vn 0.522059 0.054243 0.851183 +vn 0.000000 0.054620 0.998507 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.253603 -0.198906 0.946637 +vn 0.224256 0.085466 0.970775 +vn 0.129333 -0.136787 0.982121 +vn 0.224256 0.085466 0.970775 +vn 0.000000 0.054620 0.998507 +vn 0.379146 -0.136670 0.915188 +vn 0.489963 -0.198913 0.848746 +vn 0.559013 0.035015 0.828420 +vn 0.379146 -0.136670 0.915188 +vn 0.559013 0.035015 0.828420 +vn 0.224256 0.085466 0.970775 +vn 0.268901 -0.548039 0.792052 +vn 0.298761 -0.625313 0.720920 +vn 0.379146 -0.136670 0.915188 +vn 0.268901 -0.548039 0.792052 +vn 0.379146 -0.136670 0.915188 +vn 0.253603 -0.198906 0.946637 +vn 0.369884 -0.548374 0.749982 +vn 0.390067 -0.625315 0.675892 +vn 0.489963 -0.198913 0.848746 +vn 0.369884 -0.548374 0.749982 +vn 0.489963 -0.198913 0.848746 +vn 0.379146 -0.136670 0.915188 +vn 0.298761 -0.625313 0.720920 +vn 0.076426 -0.979861 0.184474 +vn 0.088294 -0.979865 0.179080 +vn 0.369884 -0.548374 0.749982 +vn 0.088294 -0.979865 0.179080 +vn 0.099785 -0.979863 0.172949 +vn 0.088294 -0.979865 0.179080 +vn -0.035375 -0.996795 -0.071753 +vn -0.039978 -0.996795 -0.069293 +vn 0.076426 -0.979861 0.184474 +vn -0.030617 -0.996795 -0.073907 +vn -0.035375 -0.996795 -0.071753 +vn 0.201834 -0.625309 0.753825 +vn 0.051625 -0.979859 0.192902 +vn 0.064178 -0.979856 0.189113 +vn 0.268901 -0.548039 0.792052 +vn 0.064178 -0.979856 0.189113 +vn 0.076426 -0.979861 0.184474 +vn 0.064178 -0.979856 0.189113 +vn -0.025707 -0.996795 -0.075754 +vn -0.030617 -0.996795 -0.073907 +vn 0.051625 -0.979859 0.192902 +vn -0.020680 -0.996795 -0.077279 +vn -0.025707 -0.996795 -0.075754 +vn 0.054845 -0.548214 0.834538 +vn 0.101911 -0.625316 0.773688 +vn 0.129333 -0.136787 0.982121 +vn 0.054845 -0.548214 0.834538 +vn 0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.163032 -0.548348 0.820204 +vn 0.201834 -0.625309 0.753825 +vn 0.253603 -0.198906 0.946637 +vn 0.253603 -0.198906 0.946637 +vn 0.129333 -0.136787 0.982121 +vn 0.163032 -0.548348 0.820204 +vn 0.101911 -0.625316 0.773688 +vn 0.026053 -0.979864 0.197959 +vn 0.038902 -0.979864 0.195841 +vn 0.163032 -0.548348 0.820204 +vn 0.038902 -0.979864 0.195841 +vn 0.051625 -0.979859 0.192902 +vn 0.038902 -0.979864 0.195841 +vn -0.015585 -0.996795 -0.078466 +vn -0.020680 -0.996795 -0.077279 +vn 0.026053 -0.979864 0.197959 +vn -0.010437 -0.996795 -0.079315 +vn -0.015585 -0.996795 -0.078466 +vn -0.000016 -0.625302 0.780383 +vn -0.000027 -0.979855 0.199708 +vn 0.013072 -0.979860 0.199255 +vn 0.054845 -0.548214 0.834538 +vn 0.013072 -0.979860 0.199255 +vn 0.026053 -0.979864 0.197959 +vn 0.013072 -0.979860 0.199255 +vn -0.005235 -0.996795 -0.079826 +vn -0.010437 -0.996795 -0.079315 +vn -0.000027 -0.979855 0.199708 +vn 0.000012 -0.996795 -0.079997 +vn -0.005235 -0.996795 -0.079826 +vn -0.379146 -0.136670 0.915188 +vn -0.253603 -0.198906 0.946637 +vn -0.224256 0.085466 0.970775 +vn -0.224256 0.085466 0.970775 +vn -0.559013 0.035015 0.828420 +vn -0.379146 -0.136670 0.915188 +vn -0.129333 -0.136787 0.982121 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 0.054620 0.998507 +vn 0.000000 0.054620 0.998507 +vn -0.224256 0.085466 0.970775 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.101942 -0.625316 0.773684 +vn -0.129333 -0.136787 0.982121 +vn -0.163052 -0.548348 0.820200 +vn -0.129333 -0.136787 0.982121 +vn -0.253603 -0.198906 0.946637 +vn -0.054866 -0.548214 0.834537 +vn -0.000016 -0.625302 0.780383 +vn 0.000000 -0.198908 0.980018 +vn 0.000000 -0.198908 0.980018 +vn -0.129333 -0.136787 0.982121 +vn -0.054866 -0.548214 0.834537 +vn -0.101942 -0.625316 0.773684 +vn -0.026105 -0.979864 0.197952 +vn -0.013125 -0.979860 0.199252 +vn -0.054866 -0.548214 0.834537 +vn -0.013125 -0.979860 0.199252 +vn -0.000027 -0.979855 0.199708 +vn -0.013125 -0.979860 0.199252 +vn 0.005260 -0.996795 -0.079825 +vn 0.000012 -0.996795 -0.079997 +vn -0.026105 -0.979864 0.197952 +vn 0.010461 -0.996795 -0.079312 +vn 0.005260 -0.996795 -0.079825 +vn -0.201864 -0.625309 0.753817 +vn -0.051676 -0.979859 0.192887 +vn -0.038954 -0.979864 0.195830 +vn -0.163052 -0.548348 0.820200 +vn -0.038954 -0.979864 0.195830 +vn -0.026105 -0.979864 0.197952 +vn -0.038954 -0.979864 0.195830 +vn 0.015609 -0.996795 -0.078461 +vn 0.010461 -0.996795 -0.079312 +vn -0.051676 -0.979859 0.192887 +vn 0.020704 -0.996795 -0.077272 +vn 0.015609 -0.996795 -0.078461 +vn -0.369902 -0.548374 0.749972 +vn -0.298790 -0.625312 0.720908 +vn -0.379146 -0.136670 0.915188 +vn -0.379146 -0.136670 0.915188 +vn -0.489963 -0.198913 0.848746 +vn -0.369902 -0.548374 0.749972 +vn -0.268920 -0.548039 0.792045 +vn -0.201864 -0.625309 0.753817 +vn -0.253603 -0.198906 0.946637 +vn -0.253603 -0.198906 0.946637 +vn -0.379146 -0.136670 0.915188 +vn -0.268920 -0.548039 0.792045 +vn -0.298790 -0.625312 0.720908 +vn -0.076475 -0.979861 0.184454 +vn -0.064229 -0.979856 0.189096 +vn -0.268920 -0.548039 0.792045 +vn -0.064229 -0.979856 0.189096 +vn -0.051676 -0.979859 0.192887 +vn -0.064229 -0.979856 0.189096 +vn 0.025730 -0.996795 -0.075746 +vn 0.020704 -0.996795 -0.077272 +vn -0.076475 -0.979861 0.184454 +vn 0.030640 -0.996795 -0.073898 +vn 0.025730 -0.996795 -0.075746 +vn -0.390094 -0.625314 0.675876 +vn -0.099830 -0.979863 0.172922 +vn -0.088341 -0.979865 0.179057 +vn -0.369902 -0.548374 0.749972 +vn -0.088341 -0.979865 0.179057 +vn -0.076475 -0.979861 0.184454 +vn -0.088341 -0.979865 0.179057 +vn 0.035397 -0.996795 -0.071742 +vn 0.030640 -0.996795 -0.073898 +vn -0.099830 -0.979863 0.172922 +vn 0.039999 -0.996795 -0.069281 +vn 0.035397 -0.996795 -0.071742 +vn -0.863839 0.062737 0.499846 +vn -0.865986 0.007573 0.500011 +vn -0.679581 0.085468 0.728605 +vn -0.679581 0.085468 0.728605 +vn -0.559013 0.035015 0.828420 +vn -0.863839 0.062737 0.499846 +vn -0.785908 -0.136554 0.603077 +vn -0.692977 -0.198918 0.692975 +vn -0.679581 0.085468 0.728605 +vn -0.785908 -0.136554 0.603077 +vn -0.679581 0.085468 0.728605 +vn -0.865986 0.007573 0.500011 +vn -0.603081 -0.136554 0.785905 +vn -0.489963 -0.198913 0.848746 +vn -0.559013 0.035015 0.828420 +vn -0.559013 0.035015 0.828420 +vn -0.679581 0.085468 0.728605 +vn -0.603081 -0.136554 0.785905 +vn -0.551523 -0.548295 0.628645 +vn -0.475140 -0.625305 0.619061 +vn -0.603081 -0.136554 0.785905 +vn -0.603081 -0.136554 0.785905 +vn -0.692977 -0.198918 0.692975 +vn -0.551523 -0.548295 0.628645 +vn -0.464597 -0.548113 0.695501 +vn -0.390094 -0.625314 0.675876 +vn -0.489963 -0.198913 0.848746 +vn -0.464597 -0.548113 0.695501 +vn -0.489963 -0.198913 0.848746 +vn -0.603081 -0.136554 0.785905 +vn -0.475140 -0.625305 0.619061 +vn -0.121608 -0.979857 0.158406 +vn -0.110944 -0.979858 0.166042 +vn -0.464597 -0.548113 0.695501 +vn -0.110944 -0.979858 0.166042 +vn -0.099830 -0.979863 0.172922 +vn -0.110944 -0.979858 0.166042 +vn 0.044445 -0.996795 -0.066514 +vn 0.039999 -0.996795 -0.069281 +vn -0.121608 -0.979857 0.158406 +vn 0.048715 -0.996795 -0.063453 +vn 0.044445 -0.996795 -0.066514 +vn -0.551819 -0.625315 0.551794 +vn -0.141203 -0.979865 0.141164 +vn -0.131702 -0.979863 0.150080 +vn -0.551523 -0.548295 0.628645 +vn -0.131702 -0.979863 0.150080 +vn -0.121608 -0.979857 0.158406 +vn -0.131702 -0.979863 0.150080 +vn 0.052767 -0.996795 -0.060128 +vn 0.048715 -0.996795 -0.063453 +vn -0.141203 -0.979865 0.141164 +vn 0.056577 -0.996795 -0.056559 +vn 0.052767 -0.996795 -0.060128 +vn -0.695513 -0.548117 0.464574 +vn -0.619082 -0.625304 0.475112 +vn -0.785908 -0.136554 0.603077 +vn -0.785908 -0.136554 0.603077 +vn -0.848748 -0.198912 0.489960 +vn -0.695513 -0.548117 0.464574 +vn -0.628661 -0.548296 0.551504 +vn -0.551819 -0.625315 0.551794 +vn -0.692977 -0.198918 0.692975 +vn -0.628661 -0.548296 0.551504 +vn -0.692977 -0.198918 0.692975 +vn -0.785908 -0.136554 0.603077 +vn -0.619082 -0.625304 0.475112 +vn -0.158439 -0.979857 0.121565 +vn -0.150116 -0.979863 0.131661 +vn -0.628661 -0.548296 0.551504 +vn -0.150116 -0.979863 0.131661 +vn -0.141203 -0.979865 0.141164 +vn -0.150116 -0.979863 0.131661 +vn 0.060145 -0.996795 -0.052748 +vn 0.056577 -0.996795 -0.056559 +vn -0.158439 -0.979857 0.121565 +vn 0.063469 -0.996795 -0.048696 +vn 0.060145 -0.996795 -0.052748 +vn -0.675893 -0.625315 0.390065 +vn -0.172949 -0.979863 0.099784 +vn -0.166073 -0.979858 0.110900 +vn -0.695513 -0.548117 0.464574 +vn -0.166073 -0.979858 0.110900 +vn -0.158439 -0.979857 0.121565 +vn -0.166073 -0.979858 0.110900 +vn 0.066529 -0.996795 -0.044425 +vn 0.063469 -0.996795 -0.048696 +vn -0.172949 -0.979863 0.099784 +vn 0.069293 -0.996795 -0.039977 +vn 0.066529 -0.996795 -0.044425 +vn -0.998818 0.048476 0.003588 +vn -0.974045 -0.216081 0.067421 +vn -0.959759 -0.214953 0.180714 +vn -0.915190 -0.136671 0.379143 +vn -0.848748 -0.198912 0.489960 +vn -0.865986 0.007573 0.500011 +vn -0.915190 -0.136671 0.379143 +vn -0.865986 0.007573 0.500011 +vn -0.972486 0.075824 0.220276 +vn -0.792052 -0.548040 0.268898 +vn -0.720921 -0.625312 0.298759 +vn -0.915190 -0.136671 0.379143 +vn -0.792052 -0.548040 0.268898 +vn -0.915190 -0.136671 0.379143 +vn -0.959759 -0.214953 0.180714 +vn -0.749983 -0.548375 0.369880 +vn -0.675893 -0.625315 0.390065 +vn -0.848748 -0.198912 0.489960 +vn -0.749983 -0.548375 0.369880 +vn -0.848748 -0.198912 0.489960 +vn -0.915190 -0.136671 0.379143 +vn -0.720921 -0.625312 0.298759 +vn -0.184475 -0.979861 0.076425 +vn -0.179081 -0.979865 0.088293 +vn -0.749983 -0.548375 0.369880 +vn -0.179081 -0.979865 0.088293 +vn -0.172949 -0.979863 0.099784 +vn -0.179081 -0.979865 0.088293 +vn 0.071753 -0.996795 -0.035375 +vn 0.069293 -0.996795 -0.039977 +vn -0.184475 -0.979861 0.076425 +vn 0.073908 -0.996795 -0.030617 +vn 0.071753 -0.996795 -0.035375 +vn -0.787262 -0.610234 0.088501 +vn -0.217514 -0.975719 0.025702 +vn -0.189113 -0.979856 0.064178 +vn -0.792052 -0.548040 0.268898 +vn -0.189113 -0.979856 0.064178 +vn -0.184475 -0.979861 0.076425 +vn -0.189113 -0.979856 0.064178 +vn 0.075754 -0.996795 -0.025706 +vn 0.073908 -0.996795 -0.030617 +vn -0.217514 -0.975719 0.025702 +vn 0.079340 -0.996763 -0.012975 +vn 0.075754 -0.996795 -0.025706 +vn -0.959759 -0.214953 0.180714 +vn -0.974045 -0.216081 0.067421 +vn -0.774567 -0.626221 0.088845 +vn -0.787262 -0.610234 0.088501 +vn -0.959759 -0.214953 0.180714 +vn -0.059975 -0.994232 0.088919 +vn -0.217514 -0.975719 0.025702 +vn -0.787262 -0.610234 0.088501 +vn -0.059975 -0.994232 0.088919 +vn -0.195626 -0.976106 0.094593 +vn -0.059975 -0.994232 0.088919 +vn -0.959759 -0.214953 0.180714 +vn -0.959759 -0.214953 0.180714 +vn -0.774567 -0.626221 0.088845 +vn -0.195626 -0.976106 0.094593 +vn -0.493340 0.119288 0.861618 +vn -0.493974 0.112906 0.862115 +vn 0.003282 0.112908 0.993600 +vn -0.494767 0.102956 0.862905 +vn -0.495785 0.089908 0.863779 +vn 0.002546 0.089909 0.995947 +vn 0.002990 0.102958 0.994681 +vn 0.002546 0.089909 0.995947 +vn 0.500192 0.089907 0.861234 +vn 0.002546 0.089909 0.995947 +vn 0.000794 0.047128 0.998889 +vn 0.522059 0.054243 0.851183 +vn -0.495785 0.089908 0.863779 +vn -0.520588 0.054246 0.852083 +vn 0.000794 0.047128 0.998889 +vn 0.003582 0.119290 0.992853 +vn 0.003282 0.112908 0.993600 +vn 0.499657 0.112906 0.858834 +vn 0.003282 0.112908 0.993600 +vn 0.002990 0.102958 0.994681 +vn 0.499945 0.102956 0.859916 +vn -0.493974 0.112906 0.862115 +vn -0.494767 0.102956 0.862905 +vn 0.002990 0.102958 0.994681 +vn -0.994681 0.102958 0.002990 +vn -0.995947 0.089909 0.002546 +vn -0.861235 0.089907 0.500190 +vn -0.859917 0.102956 0.499943 +vn -0.861235 0.089907 0.500190 +vn -0.495785 0.089908 0.863779 +vn -0.861235 0.089907 0.500190 +vn -0.863839 0.062737 0.499846 +vn -0.520588 0.054246 0.852083 +vn -0.995947 0.089909 0.002546 +vn -0.998889 0.047128 0.000794 +vn -0.863839 0.062737 0.499846 +vn -0.858038 0.119288 0.499541 +vn -0.858835 0.112906 0.499655 +vn -0.493974 0.112906 0.862115 +vn -0.858835 0.112906 0.499655 +vn -0.859917 0.102956 0.499943 +vn -0.494767 0.102956 0.862905 +vn -0.993600 0.112908 0.003282 +vn -0.994681 0.102958 0.002990 +vn -0.859917 0.102956 0.499943 +vn 0.499499 0.138592 0.855157 +vn 0.499269 0.137445 0.855476 +vn 0.860102 0.137445 0.491258 +vn 0.499366 0.128646 0.856787 +vn 0.499410 0.124651 0.857352 +vn 0.861162 0.124651 0.492811 +vn 0.860841 0.128646 0.492344 +vn 0.861162 0.124651 0.492811 +vn 0.992193 0.124653 -0.003810 +vn 0.861162 0.124651 0.492811 +vn 0.861619 0.119288 0.493338 +vn 0.992853 0.119290 -0.003582 +vn 0.499410 0.124651 0.857352 +vn 0.499543 0.119288 0.858037 +vn 0.861619 0.119288 0.493338 +vn 0.499299 0.134937 0.855858 +vn 0.499292 0.132157 0.856295 +vn 0.860531 0.132157 0.491956 +vn 0.860318 0.134936 0.491574 +vn 0.860531 0.132157 0.491956 +vn 0.991220 0.132159 -0.004236 +vn 0.860531 0.132157 0.491956 +vn 0.860841 0.128646 0.492344 +vn 0.991682 0.128649 -0.004054 +vn 0.499292 0.132157 0.856295 +vn 0.499366 0.128646 0.856787 +vn 0.860841 0.128646 0.492344 +vn 0.860140 0.138592 0.490867 +vn 0.860102 0.137445 0.491258 +vn 0.990498 0.137448 -0.004625 +vn 0.860102 0.137445 0.491258 +vn 0.860318 0.134936 0.491574 +vn 0.990844 0.134939 -0.004460 +vn 0.499269 0.137445 0.855476 +vn 0.499299 0.134937 0.855858 +vn 0.860318 0.134936 0.491574 +vn -0.991682 0.128649 0.004054 +vn -0.992193 0.124653 0.003810 +vn -0.857353 0.124650 0.499408 +vn -0.492346 0.128646 0.860840 +vn -0.492814 0.124651 0.861160 +vn 0.003810 0.124653 0.992193 +vn 0.004054 0.128649 0.991682 +vn 0.003810 0.124653 0.992193 +vn 0.499410 0.124651 0.857352 +vn 0.003810 0.124653 0.992193 +vn 0.003582 0.119290 0.992853 +vn 0.499543 0.119288 0.858037 +vn -0.492814 0.124651 0.861160 +vn -0.493340 0.119288 0.861618 +vn 0.003582 0.119290 0.992853 +vn -0.856788 0.128646 0.499364 +vn -0.857353 0.124650 0.499408 +vn -0.492814 0.124651 0.861160 +vn -0.857353 0.124650 0.499408 +vn -0.858038 0.119288 0.499541 +vn -0.493340 0.119288 0.861618 +vn -0.992193 0.124653 0.003810 +vn -0.992853 0.119290 0.003582 +vn -0.858038 0.119288 0.499541 +vn -0.490869 0.138592 0.860139 +vn -0.491260 0.137445 0.860100 +vn 0.004625 0.137448 0.990498 +vn -0.491576 0.134936 0.860317 +vn -0.491957 0.132157 0.860530 +vn 0.004236 0.132159 0.991220 +vn 0.004460 0.134939 0.990844 +vn 0.004236 0.132159 0.991220 +vn 0.499292 0.132157 0.856295 +vn 0.004236 0.132159 0.991220 +vn 0.004054 0.128649 0.991682 +vn 0.499366 0.128646 0.856787 +vn -0.491957 0.132157 0.860530 +vn -0.492346 0.128646 0.860840 +vn 0.004054 0.128649 0.991682 +vn 0.004983 0.138595 0.990337 +vn 0.004625 0.137448 0.990498 +vn 0.499269 0.137445 0.855476 +vn 0.004625 0.137448 0.990498 +vn 0.004460 0.134939 0.990844 +vn 0.499299 0.134937 0.855858 +vn -0.491260 0.137445 0.860100 +vn -0.491576 0.134936 0.860317 +vn 0.004460 0.134939 0.990844 +vn -0.990844 0.134939 0.004460 +vn -0.991220 0.132159 0.004236 +vn -0.856296 0.132157 0.499291 +vn -0.855859 0.134936 0.499297 +vn -0.856296 0.132157 0.499291 +vn -0.491957 0.132157 0.860530 +vn -0.856296 0.132157 0.499291 +vn -0.856788 0.128646 0.499364 +vn -0.492346 0.128646 0.860840 +vn -0.991220 0.132159 0.004236 +vn -0.991682 0.128649 0.004054 +vn -0.856788 0.128646 0.499364 +vn -0.855158 0.138592 0.499497 +vn -0.855477 0.137445 0.499267 +vn -0.491260 0.137445 0.860100 +vn -0.855477 0.137445 0.499267 +vn -0.855859 0.134936 0.499297 +vn -0.491576 0.134936 0.860317 +vn -0.990498 0.137448 0.004625 +vn -0.990844 0.134939 0.004460 +vn -0.855859 0.134936 0.499297 +s off +g glass:revolvedSurface2 +usemtl initialShadingGroup +f 481/1/1 2/2/2 482/3/3 +f 260/4/4 3/5/5 261/6/6 +f 220/7/7 6/8/8 221/9/9 +f 81/10/10 7/11/11 83/12/12 +f 11/13/13 10/14/14 46/15/15 +f 13/16/16 9/17/17 11/13/18 +f 14/18/19 33/19/20 35/20/21 +f 15/21/22 18/22/23 19/23/24 +f 18/22/25 28/24/26 30/25/27 +f 19/23/28 22/26/29 23/27/30 +f 23/27/31 22/26/32 26/28/33 +f 25/29/34 21/30/35 23/27/36 +f 1/31/37 25/29/38 26/28/39 +f 24/32/40 26/28/41 27/33/42 +f 31/34/43 30/25/44 28/24/45 +f 27/33/46 22/26/47 30/25/48 +f 20/35/49 27/33/50 31/34/51 +f 29/36/52 31/34/53 32/37/54 +f 33/19/55 41/38/56 43/39/57 +f 35/20/58 36/40/59 38/41/60 +f 39/42/61 38/41/62 36/40/63 +f 32/37/64 28/24/65 38/41/66 +f 16/43/67 32/37/68 39/42/69 +f 37/44/70 39/42/71 40/45/72 +f 44/46/73 43/39/74 41/38/75 +f 40/45/76 36/40/77 43/39/78 +f 34/47/79 40/45/80 44/46/81 +f 42/48/82 44/46/83 45/49/84 +f 64/50/85 49/51/86 48/52/87 +f 48/52/88 49/51/89 51/53/90 +f 49/51/91 57/54/92 59/55/93 +f 51/53/94 52/56/95 54/57/96 +f 55/58/97 54/57/98 52/56/99 +f 45/49/100 41/38/101 54/57/102 +f 12/59/103 45/49/104 55/58/105 +f 53/60/106 55/58/107 56/61/108 +f 60/62/109 59/55/110 57/54/111 +f 56/61/112 52/56/113 59/55/114 +f 50/63/115 56/61/116 60/62/117 +f 58/64/118 60/62/119 61/65/120 +f 62/66/121 70/67/122 72/68/123 +f 64/50/124 65/69/125 67/70/126 +f 68/71/127 67/70/128 65/69/129 +f 61/65/130 57/54/131 67/70/132 +f 47/72/133 61/65/134 68/71/135 +f 66/73/136 68/71/137 69/74/138 +f 73/75/139 72/68/140 70/67/141 +f 69/74/142 65/69/143 72/68/144 +f 63/76/145 69/74/146 73/75/147 +f 71/77/148 73/75/149 74/78/150 +f 77/79/151 76/80/152 79/81/153 +f 78/82/154 75/83/155 77/79/156 +f 9/17/157 78/82/158 79/81/159 +f 11/13/160 79/81/161 80/84/162 +f 82/85/163 5/86/164 81/10/165 +f 75/83/166 82/85/167 83/12/168 +f 77/79/169 83/12/170 84/87/171 +f 181/88/172 150/89/173 149/90/174 +f 90/91/175 89/92/176 87/93/177 +f 10/14/178 89/92/179 90/91/180 +f 90/91/181 106/94/182 108/95/183 +f 92/96/184 93/97/185 95/98/186 +f 93/97/187 101/99/188 103/100/189 +f 95/98/190 96/101/191 98/102/192 +f 99/103/193 98/102/194 96/101/195 +f 74/78/196 70/67/197 98/102/198 +f 8/104/199 74/78/200 99/103/201 +f 97/105/202 99/103/203 100/106/204 +f 104/107/205 103/100/206 101/99/207 +f 100/106/208 96/101/209 103/100/210 +f 94/108/211 100/106/212 104/107/213 +f 102/109/214 104/107/215 105/110/216 +f 106/94/217 114/111/218 116/112/219 +f 108/95/220 109/113/221 111/114/222 +f 112/115/223 111/114/224 109/113/225 +f 105/110/226 101/99/227 111/114/228 +f 91/116/229 105/110/230 112/115/231 +f 110/117/232 112/115/233 113/118/234 +f 117/119/235 116/112/236 114/111/237 +f 113/118/238 109/113/239 116/112/240 +f 107/120/241 113/118/242 117/119/243 +f 115/121/244 117/119/245 118/122/246 +f 119/123/247 135/124/248 137/125/249 +f 121/126/250 122/127/251 124/128/252 +f 122/127/253 130/129/254 132/130/255 +f 124/128/256 125/131/257 127/132/258 +f 128/133/259 127/132/260 125/131/261 +f 118/122/262 114/111/263 127/132/264 +f 88/134/265 118/122/266 128/133/267 +f 126/135/268 128/133/269 129/136/270 +f 133/137/271 132/130/272 130/129/273 +f 129/136/274 125/131/275 132/130/276 +f 123/138/277 129/136/278 133/137/279 +f 131/139/280 133/137/281 134/140/282 +f 135/124/283 143/141/284 145/142/285 +f 137/125/286 138/143/287 140/144/288 +f 141/145/289 140/144/290 138/143/291 +f 134/140/292 130/129/293 140/144/294 +f 120/146/295 134/140/296 141/145/297 +f 139/147/298 141/145/299 142/148/300 +f 146/149/301 145/142/302 143/141/303 +f 142/148/304 138/143/305 145/142/306 +f 136/150/307 142/148/308 146/149/309 +f 144/151/310 146/149/311 147/152/312 +f 119/123/313 87/93/314 149/90/315 +f 150/89/316 166/153/317 168/154/318 +f 152/155/319 153/156/320 155/157/321 +f 153/156/322 161/158/323 163/159/324 +f 155/157/325 156/160/326 158/161/327 +f 159/162/328 158/161/329 156/160/330 +f 147/152/331 143/141/332 158/161/333 +f 86/163/334 147/152/335 159/162/336 +f 157/164/337 159/162/338 160/165/339 +f 164/166/340 163/159/341 161/158/342 +f 160/165/343 156/160/344 163/159/345 +f 154/167/346 160/165/347 164/166/348 +f 162/168/349 164/166/350 165/169/351 +f 166/153/352 174/170/353 176/171/354 +f 168/154/355 169/172/356 171/173/357 +f 172/174/358 171/173/359 169/172/360 +f 165/169/361 161/158/362 171/173/363 +f 151/175/364 165/169/365 172/174/366 +f 170/176/367 172/174/368 173/177/369 +f 177/178/370 176/171/371 174/170/372 +f 173/177/373 169/172/374 176/171/375 +f 167/179/376 173/177/377 177/178/378 +f 175/180/379 177/178/380 178/181/381 +f 197/182/382 182/183/383 181/88/384 +f 181/88/385 182/183/386 184/184/387 +f 182/183/388 190/185/389 192/186/390 +f 184/184/391 185/187/392 187/188/393 +f 188/189/394 187/188/395 185/187/396 +f 178/181/397 174/170/398 187/188/399 +f 148/190/400 178/181/401 188/189/402 +f 186/191/403 188/189/404 189/192/405 +f 193/193/406 192/186/407 190/185/408 +f 189/192/409 185/187/410 192/186/411 +f 183/194/412 189/192/413 193/193/414 +f 191/195/415 193/193/416 194/196/417 +f 205/197/418 198/198/419 197/182/420 +f 197/182/421 198/198/422 200/199/423 +f 201/200/424 200/199/425 198/198/426 +f 194/196/427 190/185/428 200/199/429 +f 180/201/430 194/196/431 201/200/432 +f 199/202/433 201/200/434 202/203/435 +f 206/204/436 205/197/437 203/205/438 +f 202/203/439 198/198/440 205/197/441 +f 196/206/442 202/203/443 206/204/444 +f 204/207/445 206/204/446 207/208/447 +f 213/209/448 208/210/449 214/211/450 +f 211/212/451 210/213/452 209/214/453 +f 80/84/454 76/80/455 210/213/456 +f 10/14/457 80/84/458 211/212/459 +f 89/92/460 211/212/461 212/215/462 +f 7/11/463 213/209/464 84/87/465 +f 76/80/466 84/87/467 214/211/468 +f 210/213/469 214/211/470 215/216/471 +f 218/217/472 217/218/473 216/219/474 +f 212/215/475 209/214/476 217/218/477 +f 87/93/478 212/215/479 218/217/480 +f 149/90/481 218/217/482 219/220/483 +f 208/210/484 220/7/485 215/216/486 +f 209/214/487 215/216/488 221/9/489 +f 217/218/490 221/9/491 222/221/492 +f 236/222/493 223/223/494 238/224/495 +f 226/225/496 225/226/497 228/227/498 +f 227/228/499 224/229/500 226/225/501 +f 5/86/502 227/228/503 228/227/504 +f 81/10/505 228/227/506 229/230/507 +f 232/231/508 231/232/509 234/233/510 +f 233/234/511 230/235/512 232/231/513 +f 224/229/514 233/234/515 234/233/516 +f 226/225/517 234/233/518 235/236/519 +f 237/237/520 2/238/521 236/222/522 +f 230/235/523 237/237/524 238/224/525 +f 232/231/526 238/224/527 239/239/528 +f 246/240/529 245/241/530 240/242/531 +f 243/243/532 242/244/533 241/245/534 +f 229/230/535 225/226/536 242/244/537 +f 7/11/538 229/230/539 243/243/540 +f 213/209/541 243/243/542 244/246/543 +f 244/246/544 241/245/545 245/241/546 +f 208/210/547 244/246/548 246/240/549 +f 220/7/550 246/240/551 247/247/552 +f 253/248/553 248/249/554 254/250/555 +f 251/251/556 250/252/557 249/253/558 +f 235/236/559 231/232/560 250/252/561 +f 225/226/562 235/236/563 251/251/564 +f 242/244/565 251/251/566 252/254/567 +f 223/223/568 253/248/569 239/239/570 +f 231/232/571 239/239/572 254/250/573 +f 250/252/574 254/250/575 255/255/576 +f 258/256/577 257/257/578 256/258/579 +f 252/254/580 249/253/581 257/257/582 +f 241/245/583 252/254/584 258/256/585 +f 245/241/586 258/256/587 259/259/588 +f 248/249/589 260/4/590 255/255/591 +f 249/253/592 255/255/593 261/6/594 +f 257/257/595 261/6/596 262/260/597 +f 452/261/598 451/262/599 5/263/600 +f 330/264/601 264/265/602 331/266/603 +f 267/267/604 265/268/605 297/269/606 +f 179/270/607 85/271/608 267/267/609 +f 268/272/610 284/273/611 286/274/612 +f 270/275/613 271/276/614 273/277/615 +f 271/276/616 279/278/617 281/279/618 +f 273/277/619 274/280/620 276/281/621 +f 277/282/622 276/281/623 274/280/624 +f 207/208/625 203/205/626 276/281/627 +f 4/283/628 207/208/629 277/282/630 +f 275/284/631 277/282/632 278/285/633 +f 282/286/634 281/279/635 279/278/636 +f 278/285/637 274/280/638 281/279/639 +f 272/287/640 278/285/641 282/286/642 +f 280/288/643 282/286/644 283/289/645 +f 284/273/646 292/290/647 294/291/648 +f 286/274/649 287/292/650 289/293/651 +f 290/294/652 289/293/653 287/292/654 +f 283/289/655 279/278/656 289/293/657 +f 269/295/658 283/289/659 290/294/660 +f 288/296/661 290/294/662 291/297/663 +f 295/298/664 294/291/665 292/290/666 +f 291/297/667 287/292/668 294/291/669 +f 285/299/670 291/297/671 295/298/672 +f 293/300/673 295/298/674 296/301/675 +f 297/269/676 313/302/677 315/303/678 +f 299/304/679 300/305/680 302/306/681 +f 300/305/682 308/307/683 310/308/684 +f 302/306/685 303/309/686 305/310/687 +f 306/311/688 305/310/689 303/309/690 +f 296/301/691 292/290/692 305/310/693 +f 266/312/694 296/301/695 306/311/696 +f 304/313/697 306/311/698 307/314/699 +f 311/315/700 310/308/701 308/307/702 +f 307/314/703 303/309/704 310/308/705 +f 301/316/706 307/314/707 311/315/708 +f 309/317/709 311/315/710 312/318/711 +f 313/302/712 321/319/713 323/320/714 +f 315/303/715 316/321/716 318/322/717 +f 319/323/718 318/322/719 316/321/720 +f 312/318/721 308/307/722 318/322/723 +f 298/324/724 312/318/725 319/323/726 +f 317/325/727 319/323/728 320/326/729 +f 324/327/730 323/320/731 321/319/732 +f 320/326/733 316/321/734 323/320/735 +f 314/328/736 320/326/737 324/327/738 +f 322/329/739 324/327/740 325/330/741 +f 327/331/742 326/332/743 328/333/744 +f 219/220/745 216/219/746 327/331/747 +f 85/271/748 219/220/749 328/333/750 +f 267/267/751 328/333/752 329/334/753 +f 222/221/754 6/8/755 330/264/756 +f 216/219/757 222/221/758 331/266/759 +f 327/331/760 331/266/761 332/335/762 +f 427/336/763 397/337/764 396/338/765 +f 337/339/766 336/340/767 334/341/768 +f 265/268/769 336/340/770 337/339/771 +f 337/339/772 353/342/773 355/343/774 +f 339/344/775 340/345/776 342/346/777 +f 340/345/778 348/347/779 350/348/780 +f 342/346/781 343/349/782 345/350/783 +f 346/351/784 345/350/785 343/349/786 +f 325/330/787 321/319/788 345/350/789 +f 263/352/790 325/330/791 346/351/792 +f 344/353/793 346/351/794 347/354/795 +f 351/355/796 350/348/797 348/347/798 +f 347/354/799 343/349/800 350/348/801 +f 341/356/802 347/354/803 351/355/804 +f 349/357/805 351/355/806 352/358/807 +f 353/342/808 361/359/809 363/360/810 +f 355/343/811 356/361/812 358/362/813 +f 359/363/814 358/362/815 356/361/816 +f 352/358/817 348/347/818 358/362/819 +f 338/364/820 352/358/821 359/363/822 +f 357/365/823 359/363/824 360/366/825 +f 364/367/826 363/360/827 361/359/828 +f 360/366/829 356/361/830 363/360/831 +f 354/368/832 360/366/833 364/367/834 +f 362/369/835 364/367/836 365/370/837 +f 366/371/838 382/372/839 384/373/840 +f 368/374/841 369/375/842 371/376/843 +f 369/375/844 377/377/845 379/378/846 +f 371/376/847 372/379/848 374/380/849 +f 375/381/850 374/380/851 372/379/852 +f 365/370/853 361/359/854 374/380/855 +f 335/382/856 365/370/857 375/381/858 +f 373/383/859 375/381/860 376/384/861 +f 380/385/862 379/378/863 377/377/864 +f 376/384/865 372/379/866 379/378/867 +f 370/386/868 376/384/869 380/385/870 +f 378/387/871 380/385/872 381/388/873 +f 382/372/874 390/389/875 392/390/876 +f 384/373/877 385/391/878 387/392/879 +f 388/393/880 387/392/881 385/391/882 +f 381/388/883 377/377/884 387/392/885 +f 367/394/886 381/388/887 388/393/888 +f 386/395/889 388/393/890 389/396/891 +f 393/397/892 392/390/893 390/389/894 +f 389/396/895 385/391/896 392/390/897 +f 383/398/898 389/396/899 393/397/900 +f 391/399/901 393/397/902 394/400/903 +f 366/371/904 334/341/905 396/338/906 +f 397/337/907 413/401/908 415/402/909 +f 399/403/910 400/404/911 402/405/912 +f 400/404/913 408/406/914 410/407/915 +f 402/405/916 403/408/917 405/409/918 +f 406/410/919 405/409/920 403/408/921 +f 394/400/922 390/389/923 405/409/924 +f 333/411/925 394/400/926 406/410/927 +f 404/412/928 406/410/929 407/413/930 +f 411/414/931 410/407/932 408/406/933 +f 407/413/934 403/408/935 410/407/936 +f 401/415/937 407/413/938 411/414/939 +f 409/416/940 411/414/941 412/417/942 +f 413/401/943 421/418/944 423/419/945 +f 415/402/946 416/420/947 418/421/948 +f 419/422/949 418/421/950 416/420/951 +f 412/417/952 408/406/953 418/421/954 +f 398/423/955 412/417/956 419/422/957 +f 417/424/958 419/422/959 420/425/960 +f 424/426/961 423/419/962 421/418/963 +f 420/425/964 416/420/965 423/419/966 +f 414/427/967 420/425/968 424/426/969 +f 422/428/970 424/426/971 425/429/972 +f 428/430/973 427/336/974 13/431/975 +f 427/336/976 428/430/977 430/432/978 +f 428/430/979 436/433/980 438/434/981 +f 430/432/982 431/435/983 433/436/984 +f 434/437/985 433/436/986 431/435/987 +f 425/429/988 421/418/989 433/436/990 +f 395/438/991 425/429/992 434/437/993 +f 432/439/994 434/437/995 435/440/996 +f 439/441/997 438/434/998 436/433/999 +f 435/440/1000 431/435/1001 438/434/1002 +f 429/442/1003 435/440/1004 439/441/1005 +f 437/443/1006 439/441/1007 440/444/1008 +f 1/445/1009 426/446/1010 440/444/1011 +f 446/447/1012 441/448/1013 447/449/1014 +f 444/450/1015 443/451/1016 442/452/1017 +f 329/334/1018 326/332/1019 443/451/1020 +f 265/268/1021 329/334/1022 444/450/1023 +f 336/340/1024 444/450/1025 445/453/1026 +f 332/335/1027 264/265/1028 446/447/1029 +f 326/332/1030 332/335/1031 447/449/1032 +f 443/451/1033 447/449/1034 448/454/1035 +f 450/455/1036 449/456/1037 75/457/1038 +f 445/453/1039 442/452/1040 449/456/1041 +f 334/341/1042 445/453/1043 450/455/1044 +f 396/338/1045 450/455/1046 78/458/1047 +f 448/454/1048 441/448/1049 451/262/1050 +f 442/452/1051 448/454/1052 452/261/1053 +f 449/456/1054 452/261/1055 82/459/1056 +f 462/460/1057 453/461/1058 463/462/1059 +f 456/463/1060 455/464/1061 454/465/1062 +f 247/247/1063 240/242/1064 455/464/1065 +f 6/8/1066 247/247/1067 456/463/1068 +f 330/264/1069 456/463/1070 457/466/1071 +f 460/467/1072 459/468/1073 458/469/1074 +f 259/259/1075 256/258/1076 459/468/1077 +f 240/242/1078 259/259/1079 460/467/1080 +f 455/464/1081 460/467/1082 461/470/1083 +f 3/5/1084 462/460/1085 262/260/1086 +f 256/258/1087 262/260/1088 463/462/1089 +f 459/468/1090 463/462/1091 464/471/1092 +f 470/472/1093 469/473/1094 224/474/1095 +f 467/475/1096 466/476/1097 465/477/1098 +f 457/466/1099 454/465/1100 466/476/1101 +f 264/265/1102 457/466/1103 467/475/1104 +f 446/447/1105 467/475/1106 468/478/1107 +f 468/478/1108 465/477/1109 469/473/1110 +f 441/448/1111 468/478/1112 470/472/1113 +f 451/262/1114 470/472/1115 227/479/1116 +f 476/480/1117 471/481/1118 477/482/1119 +f 474/483/1120 473/484/1121 472/485/1122 +f 461/470/1123 458/469/1124 473/484/1125 +f 454/465/1126 461/470/1127 474/483/1128 +f 466/476/1129 474/483/1130 475/486/1131 +f 453/461/1132 476/480/1133 464/471/1134 +f 458/469/1135 464/471/1136 477/482/1137 +f 473/484/1138 477/482/1139 478/487/1140 +f 480/488/1141 479/489/1142 230/490/1143 +f 475/486/1144 472/485/1145 479/489/1146 +f 465/477/1147 475/486/1148 480/488/1149 +f 469/473/1150 480/488/1151 233/491/1152 +f 471/481/1153 481/1/1154 478/487/1155 +f 472/485/1156 478/487/1157 482/3/1158 +f 479/489/1159 482/3/1160 237/492/1161 +f 2/2/1162 237/492/1163 482/3/1164 +f 3/5/1165 262/260/1166 261/6/1167 +f 6/8/1168 222/221/1169 221/9/1170 +f 7/11/1171 84/87/1172 83/12/1173 +f 48/52/1174 14/18/1175 11/13/1176 +f 11/13/1177 46/15/1178 48/52/1179 +f 11/13/1180 14/18/1181 15/21/1182 +f 15/21/1183 13/16/1184 11/13/1185 +f 35/20/1186 18/22/1187 15/21/1188 +f 15/21/1189 14/18/1190 35/20/1191 +f 19/23/1192 17/493/1193 13/16/1194 +f 13/16/1195 15/21/1196 19/23/1197 +f 30/25/1198 22/26/1199 19/23/1200 +f 30/25/1201 19/23/1202 18/22/1203 +f 23/27/1204 21/30/1205 17/493/1206 +f 17/493/1207 19/23/1208 23/27/1209 +f 22/26/1210 27/33/1211 26/28/1212 +f 23/27/1213 26/28/1214 25/29/1215 +f 26/28/1216 24/32/1217 1/31/1218 +f 27/33/1219 20/35/1220 24/32/1221 +f 28/24/1222 32/37/1223 31/34/1224 +f 30/25/1225 31/34/1226 27/33/1227 +f 31/34/1228 29/36/1229 20/35/1230 +f 32/37/1231 16/43/1232 29/36/1233 +f 43/39/1234 36/40/1235 35/20/1236 +f 35/20/1237 33/19/1238 43/39/1239 +f 38/41/1240 28/24/1241 18/22/1242 +f 18/22/1243 35/20/1244 38/41/1245 +f 36/40/1246 40/45/1247 39/42/1248 +f 38/41/1249 39/42/1250 32/37/1251 +f 39/42/1252 37/44/1253 16/43/1254 +f 40/45/1255 34/47/1256 37/44/1257 +f 41/38/1258 45/49/1259 44/46/1260 +f 43/39/1261 44/46/1262 40/45/1263 +f 44/46/1264 42/48/1265 34/47/1266 +f 45/49/1267 12/59/1268 42/48/1269 +f 46/15/1270 62/66/1271 64/50/1272 +f 64/50/1273 48/52/1274 46/15/1275 +f 51/53/1276 33/19/1277 14/18/1278 +f 14/18/1279 48/52/1280 51/53/1281 +f 59/55/1282 52/56/1283 51/53/1284 +f 51/53/1285 49/51/1286 59/55/1287 +f 54/57/1288 41/38/1289 33/19/1290 +f 54/57/1291 33/19/1292 51/53/1293 +f 52/56/1294 56/61/1295 55/58/1296 +f 54/57/1297 55/58/1298 45/49/1299 +f 55/58/1300 53/60/1301 12/59/1302 +f 56/61/1303 50/63/1304 53/60/1305 +f 57/54/1306 61/65/1307 60/62/1308 +f 59/55/1309 60/62/1310 56/61/1311 +f 60/62/1312 58/64/1313 50/63/1314 +f 61/65/1315 47/72/1316 58/64/1317 +f 72/68/1318 65/69/1319 64/50/1320 +f 64/50/1321 62/66/1322 72/68/1323 +f 67/70/1324 57/54/1325 49/51/1326 +f 67/70/1327 49/51/1328 64/50/1329 +f 65/69/1330 69/74/1331 68/71/1332 +f 67/70/1333 68/71/1334 61/65/1335 +f 68/71/1336 66/73/1337 47/72/1338 +f 69/74/1339 63/76/1340 66/73/1341 +f 70/67/1342 74/78/1343 73/75/1344 +f 72/68/1345 73/75/1346 69/74/1347 +f 73/75/1348 71/77/1349 63/76/1350 +f 74/78/1351 8/104/1352 71/77/1353 +f 76/80/1354 80/84/1355 79/81/1356 +f 77/79/1357 79/81/1358 78/82/1359 +f 79/81/1360 11/13/1361 9/17/1362 +f 80/84/1363 10/14/1364 11/13/1365 +f 81/10/1366 83/12/1367 82/85/1368 +f 83/12/1369 77/79/1370 75/83/1371 +f 84/87/1372 76/80/1373 77/79/1374 +f 149/90/1375 85/271/1376 179/270/1377 +f 149/90/1378 179/270/1379 181/88/1380 +f 87/93/1381 119/123/1382 121/126/1383 +f 121/126/1384 90/91/1385 87/93/1386 +f 92/96/1387 46/15/1388 10/14/1389 +f 10/14/1390 90/91/1391 92/96/1392 +f 108/95/1393 93/97/1394 92/96/1395 +f 108/95/1396 92/96/1397 90/91/1398 +f 95/98/1399 62/66/1400 46/15/1401 +f 95/98/1402 46/15/1403 92/96/1404 +f 103/100/1405 96/101/1406 95/98/1407 +f 103/100/1408 95/98/1409 93/97/1410 +f 98/102/1411 70/67/1412 62/66/1413 +f 98/102/1414 62/66/1415 95/98/1416 +f 96/101/1417 100/106/1418 99/103/1419 +f 98/102/1420 99/103/1421 74/78/1422 +f 99/103/1423 97/105/1424 8/104/1425 +f 100/106/1426 94/108/1427 97/105/1428 +f 101/99/1429 105/110/1430 104/107/1431 +f 103/100/1432 104/107/1433 100/106/1434 +f 104/107/1435 102/109/1436 94/108/1437 +f 105/110/1438 91/116/1439 102/109/1440 +f 116/112/1441 109/113/1442 108/95/1443 +f 116/112/1444 108/95/1445 106/94/1446 +f 111/114/1447 101/99/1448 93/97/1449 +f 93/97/1450 108/95/1451 111/114/1452 +f 109/113/1453 113/118/1454 112/115/1455 +f 111/114/1456 112/115/1457 105/110/1458 +f 112/115/1459 110/117/1460 91/116/1461 +f 113/118/1462 107/120/1463 110/117/1464 +f 114/111/1465 118/122/1466 117/119/1467 +f 116/112/1468 117/119/1469 113/118/1470 +f 117/119/1471 115/121/1472 107/120/1473 +f 118/122/1474 88/134/1475 115/121/1476 +f 137/125/1477 122/127/1478 121/126/1479 +f 121/126/1480 119/123/1481 137/125/1482 +f 124/128/1483 106/94/1484 90/91/1485 +f 90/91/1486 121/126/1487 124/128/1488 +f 132/130/1489 125/131/1490 124/128/1491 +f 132/130/1492 124/128/1493 122/127/1494 +f 127/132/1495 114/111/1496 106/94/1497 +f 106/94/1498 124/128/1499 127/132/1500 +f 125/131/1501 129/136/1502 128/133/1503 +f 127/132/1504 128/133/1505 118/122/1506 +f 128/133/1507 126/135/1508 88/134/1509 +f 129/136/1510 123/138/1511 126/135/1512 +f 130/129/1513 134/140/1514 133/137/1515 +f 132/130/1516 133/137/1517 129/136/1518 +f 133/137/1519 131/139/1520 123/138/1521 +f 134/140/1522 120/146/1523 131/139/1524 +f 145/142/1525 138/143/1526 137/125/1527 +f 137/125/1528 135/124/1529 145/142/1530 +f 140/144/1531 130/129/1532 122/127/1533 +f 122/127/1534 137/125/1535 140/144/1536 +f 138/143/1537 142/148/1538 141/145/1539 +f 140/144/1540 141/145/1541 134/140/1542 +f 141/145/1543 139/147/1544 120/146/1545 +f 142/148/1546 136/150/1547 139/147/1548 +f 143/141/1549 147/152/1550 146/149/1551 +f 145/142/1552 146/149/1553 142/148/1554 +f 146/149/1555 144/151/1556 136/150/1557 +f 147/152/1558 86/163/1559 144/151/1560 +f 149/90/1561 150/89/1562 152/155/1563 +f 152/155/1564 119/123/1565 149/90/1566 +f 168/154/1567 153/156/1568 152/155/1569 +f 168/154/1570 152/155/1571 150/89/1572 +f 155/157/1573 135/124/1574 119/123/1575 +f 119/123/1576 152/155/1577 155/157/1578 +f 163/159/1579 156/160/1580 155/157/1581 +f 155/157/1582 153/156/1583 163/159/1584 +f 158/161/1585 143/141/1586 135/124/1587 +f 158/161/1588 135/124/1589 155/157/1590 +f 156/160/1591 160/165/1592 159/162/1593 +f 158/161/1594 159/162/1595 147/152/1596 +f 159/162/1597 157/164/1598 86/163/1599 +f 160/165/1600 154/167/1601 157/164/1602 +f 161/158/1603 165/169/1604 164/166/1605 +f 163/159/1606 164/166/1607 160/165/1608 +f 164/166/1609 162/168/1610 154/167/1611 +f 165/169/1612 151/175/1613 162/168/1614 +f 176/171/1615 169/172/1616 168/154/1617 +f 168/154/1618 166/153/1619 176/171/1620 +f 171/173/1621 161/158/1622 153/156/1623 +f 171/173/1624 153/156/1625 168/154/1626 +f 169/172/1627 173/177/1628 172/174/1629 +f 171/173/1630 172/174/1631 165/169/1632 +f 172/174/1633 170/176/1634 151/175/1635 +f 173/177/1636 167/179/1637 170/176/1638 +f 174/170/1639 178/181/1640 177/178/1641 +f 176/171/1642 177/178/1643 173/177/1644 +f 177/178/1645 175/180/1646 167/179/1647 +f 178/181/1648 148/190/1649 175/180/1650 +f 179/270/1651 195/494/1652 197/182/1653 +f 197/182/1654 181/88/1655 179/270/1656 +f 184/184/1657 166/153/1658 150/89/1659 +f 184/184/1660 150/89/1661 181/88/1662 +f 192/186/1663 185/187/1664 184/184/1665 +f 192/186/1666 184/184/1667 182/183/1668 +f 187/188/1669 174/170/1670 166/153/1671 +f 187/188/1672 166/153/1673 184/184/1674 +f 185/187/1675 189/192/1676 188/189/1677 +f 187/188/1678 188/189/1679 178/181/1680 +f 188/189/1681 186/191/1682 148/190/1683 +f 189/192/1684 183/194/1685 186/191/1686 +f 190/185/1687 194/196/1688 193/193/1689 +f 192/186/1690 193/193/1691 189/192/1692 +f 193/193/1693 191/195/1694 183/194/1695 +f 194/196/1696 180/201/1697 191/195/1698 +f 195/494/1699 203/205/1700 205/197/1701 +f 205/197/1702 197/182/1703 195/494/1704 +f 200/199/1705 190/185/1706 182/183/1707 +f 182/183/1708 197/182/1709 200/199/1710 +f 198/198/1711 202/203/1712 201/200/1713 +f 200/199/1714 201/200/1715 194/196/1716 +f 201/200/1717 199/202/1718 180/201/1719 +f 202/203/1720 196/206/1721 199/202/1722 +f 203/205/1723 207/208/1724 206/204/1725 +f 205/197/1726 206/204/1727 202/203/1728 +f 206/204/1729 204/207/1730 196/206/1731 +f 207/208/1732 4/283/1733 204/207/1734 +f 208/210/1735 215/216/1736 214/211/1737 +f 209/214/1738 212/215/1739 211/212/1740 +f 210/213/1741 211/212/1742 80/84/1743 +f 211/212/1744 89/92/1745 10/14/1746 +f 212/215/1747 87/93/1748 89/92/1749 +f 213/209/1750 214/211/1751 84/87/1752 +f 214/211/1753 210/213/1754 76/80/1755 +f 215/216/1756 209/214/1757 210/213/1758 +f 216/219/1759 219/220/1760 218/217/1761 +f 217/218/1762 218/217/1763 212/215/1764 +f 218/217/1765 149/90/1766 87/93/1767 +f 219/220/1768 85/271/1769 149/90/1770 +f 220/7/1771 221/9/1772 215/216/1773 +f 221/9/1774 217/218/1775 209/214/1776 +f 222/221/1777 216/219/1778 217/218/1779 +f 223/223/1780 239/239/1781 238/224/1782 +f 225/226/1783 229/230/1784 228/227/1785 +f 226/225/1786 228/227/1787 227/228/1788 +f 228/227/1789 81/10/1790 5/86/1791 +f 229/230/1792 7/11/1793 81/10/1794 +f 231/232/1795 235/236/1796 234/233/1797 +f 232/231/1798 234/233/1799 233/234/1800 +f 234/233/1801 226/225/1802 224/229/1803 +f 235/236/1804 225/226/1805 226/225/1806 +f 236/222/1807 238/224/1808 237/237/1809 +f 238/224/1810 232/231/1811 230/235/1812 +f 239/239/1813 231/232/1814 232/231/1815 +f 240/242/1816 247/247/1817 246/240/1818 +f 241/245/1819 244/246/1820 243/243/1821 +f 242/244/1822 243/243/1823 229/230/1824 +f 243/243/1825 213/209/1826 7/11/1827 +f 244/246/1828 208/210/1829 213/209/1830 +f 245/241/1831 246/240/1832 244/246/1833 +f 246/240/1834 220/7/1835 208/210/1836 +f 247/247/1837 6/8/1838 220/7/1839 +f 248/249/1840 255/255/1841 254/250/1842 +f 249/253/1843 252/254/1844 251/251/1845 +f 250/252/1846 251/251/1847 235/236/1848 +f 251/251/1849 242/244/1850 225/226/1851 +f 252/254/1852 241/245/1853 242/244/1854 +f 253/248/1855 254/250/1856 239/239/1857 +f 254/250/1858 250/252/1859 231/232/1860 +f 255/255/1861 249/253/1862 250/252/1863 +f 256/258/1864 259/259/1865 258/256/1866 +f 257/257/1867 258/256/1868 252/254/1869 +f 258/256/1870 245/241/1871 241/245/1872 +f 259/259/1873 240/242/1874 245/241/1875 +f 260/4/1876 261/6/1877 255/255/1878 +f 261/6/1879 257/257/1880 249/253/1881 +f 262/260/1882 256/258/1883 257/257/1884 +f 5/263/1885 82/459/1886 452/261/1887 +f 264/265/1888 332/335/1889 331/266/1890 +f 299/304/1891 268/272/1892 267/267/1893 +f 267/267/1894 297/269/1895 299/304/1896 +f 267/267/1897 268/272/1898 270/275/1899 +f 270/275/1900 179/270/1901 267/267/1902 +f 286/274/1903 271/276/1904 270/275/1905 +f 270/275/1906 268/272/1907 286/274/1908 +f 273/277/1909 195/494/1910 179/270/1911 +f 179/270/1912 270/275/1913 273/277/1914 +f 281/279/1915 274/280/1916 273/277/1917 +f 281/279/1918 273/277/1919 271/276/1920 +f 276/281/1921 203/205/1922 195/494/1923 +f 195/494/1924 273/277/1925 276/281/1926 +f 274/280/1927 278/285/1928 277/282/1929 +f 276/281/1930 277/282/1931 207/208/1932 +f 277/282/1933 275/284/1934 4/283/1935 +f 278/285/1936 272/287/1937 275/284/1938 +f 279/278/1939 283/289/1940 282/286/1941 +f 281/279/1942 282/286/1943 278/285/1944 +f 282/286/1945 280/288/1946 272/287/1947 +f 283/289/1948 269/295/1949 280/288/1950 +f 294/291/1951 287/292/1952 286/274/1953 +f 286/274/1954 284/273/1955 294/291/1956 +f 289/293/1957 279/278/1958 271/276/1959 +f 271/276/1960 286/274/1961 289/293/1962 +f 287/292/1963 291/297/1964 290/294/1965 +f 289/293/1966 290/294/1967 283/289/1968 +f 290/294/1969 288/296/1970 269/295/1971 +f 291/297/1972 285/299/1973 288/296/1974 +f 292/290/1975 296/301/1976 295/298/1977 +f 294/291/1978 295/298/1979 291/297/1980 +f 295/298/1981 293/300/1982 285/299/1983 +f 296/301/1984 266/312/1985 293/300/1986 +f 315/303/1987 300/305/1988 299/304/1989 +f 315/303/1990 299/304/1991 297/269/1992 +f 302/306/1993 284/273/1994 268/272/1995 +f 268/272/1996 299/304/1997 302/306/1998 +f 310/308/1999 303/309/2000 302/306/2001 +f 302/306/2002 300/305/2003 310/308/2004 +f 305/310/2005 292/290/2006 284/273/2007 +f 305/310/2008 284/273/2009 302/306/2010 +f 303/309/2011 307/314/2012 306/311/2013 +f 305/310/2014 306/311/2015 296/301/2016 +f 306/311/2017 304/313/2018 266/312/2019 +f 307/314/2020 301/316/2021 304/313/2022 +f 308/307/2023 312/318/2024 311/315/2025 +f 310/308/2026 311/315/2027 307/314/2028 +f 311/315/2029 309/317/2030 301/316/2031 +f 312/318/2032 298/324/2033 309/317/2034 +f 323/320/2035 316/321/2036 315/303/2037 +f 315/303/2038 313/302/2039 323/320/2040 +f 318/322/2041 308/307/2042 300/305/2043 +f 318/322/2044 300/305/2045 315/303/2046 +f 316/321/2047 320/326/2048 319/323/2049 +f 318/322/2050 319/323/2051 312/318/2052 +f 319/323/2053 317/325/2054 298/324/2055 +f 320/326/2056 314/328/2057 317/325/2058 +f 321/319/2059 325/330/2060 324/327/2061 +f 323/320/2062 324/327/2063 320/326/2064 +f 324/327/2065 322/329/2066 314/328/2067 +f 325/330/2068 263/352/2069 322/329/2070 +f 326/332/2071 329/334/2072 328/333/2073 +f 327/331/2074 328/333/2075 219/220/2076 +f 328/333/2077 267/267/2078 85/271/2079 +f 329/334/2080 265/268/2081 267/267/2082 +f 330/264/2083 331/266/2084 222/221/2085 +f 331/266/2086 327/331/2087 216/219/2088 +f 332/335/2089 326/332/2090 327/331/2091 +f 396/338/2092 9/495/2093 13/431/2094 +f 396/338/2095 13/431/2096 427/336/2097 +f 334/341/2098 366/371/2099 368/374/2100 +f 368/374/2101 337/339/2102 334/341/2103 +f 339/344/2104 297/269/2105 265/268/2106 +f 265/268/2107 337/339/2108 339/344/2109 +f 355/343/2110 340/345/2111 339/344/2112 +f 355/343/2113 339/344/2114 337/339/2115 +f 342/346/2116 313/302/2117 297/269/2118 +f 342/346/2119 297/269/2120 339/344/2121 +f 350/348/2122 343/349/2123 342/346/2124 +f 350/348/2125 342/346/2126 340/345/2127 +f 345/350/2128 321/319/2129 313/302/2130 +f 345/350/2131 313/302/2132 342/346/2133 +f 343/349/2134 347/354/2135 346/351/2136 +f 345/350/2137 346/351/2138 325/330/2139 +f 346/351/2140 344/353/2141 263/352/2142 +f 347/354/2143 341/356/2144 344/353/2145 +f 348/347/2146 352/358/2147 351/355/2148 +f 350/348/2149 351/355/2150 347/354/2151 +f 351/355/2152 349/357/2153 341/356/2154 +f 352/358/2155 338/364/2156 349/357/2157 +f 363/360/2158 356/361/2159 355/343/2160 +f 363/360/2161 355/343/2162 353/342/2163 +f 358/362/2164 348/347/2165 340/345/2166 +f 340/345/2167 355/343/2168 358/362/2169 +f 356/361/2170 360/366/2171 359/363/2172 +f 358/362/2173 359/363/2174 352/358/2175 +f 359/363/2176 357/365/2177 338/364/2178 +f 360/366/2179 354/368/2180 357/365/2181 +f 361/359/2182 365/370/2183 364/367/2184 +f 363/360/2185 364/367/2186 360/366/2187 +f 364/367/2188 362/369/2189 354/368/2190 +f 365/370/2191 335/382/2192 362/369/2193 +f 384/373/2194 369/375/2195 368/374/2196 +f 368/374/2197 366/371/2198 384/373/2199 +f 371/376/2200 353/342/2201 337/339/2202 +f 337/339/2203 368/374/2204 371/376/2205 +f 379/378/2206 372/379/2207 371/376/2208 +f 379/378/2209 371/376/2210 369/375/2211 +f 374/380/2212 361/359/2213 353/342/2214 +f 353/342/2215 371/376/2216 374/380/2217 +f 372/379/2218 376/384/2219 375/381/2220 +f 374/380/2221 375/381/2222 365/370/2223 +f 375/381/2224 373/383/2225 335/382/2226 +f 376/384/2227 370/386/2228 373/383/2229 +f 377/377/2230 381/388/2231 380/385/2232 +f 379/378/2233 380/385/2234 376/384/2235 +f 380/385/2236 378/387/2237 370/386/2238 +f 381/388/2239 367/394/2240 378/387/2241 +f 392/390/2242 385/391/2243 384/373/2244 +f 384/373/2245 382/372/2246 392/390/2247 +f 387/392/2248 377/377/2249 369/375/2250 +f 369/375/2251 384/373/2252 387/392/2253 +f 385/391/2254 389/396/2255 388/393/2256 +f 387/392/2257 388/393/2258 381/388/2259 +f 388/393/2260 386/395/2261 367/394/2262 +f 389/396/2263 383/398/2264 386/395/2265 +f 390/389/2266 394/400/2267 393/397/2268 +f 392/390/2269 393/397/2270 389/396/2271 +f 393/397/2272 391/399/2273 383/398/2274 +f 394/400/2275 333/411/2276 391/399/2277 +f 396/338/2278 397/337/2279 399/403/2280 +f 399/403/2281 366/371/2282 396/338/2283 +f 415/402/2284 400/404/2285 399/403/2286 +f 415/402/2287 399/403/2288 397/337/2289 +f 402/405/2290 382/372/2291 366/371/2292 +f 366/371/2293 399/403/2294 402/405/2295 +f 410/407/2296 403/408/2297 402/405/2298 +f 402/405/2299 400/404/2300 410/407/2301 +f 405/409/2302 390/389/2303 382/372/2304 +f 405/409/2305 382/372/2306 402/405/2307 +f 403/408/2308 407/413/2309 406/410/2310 +f 405/409/2311 406/410/2312 394/400/2313 +f 406/410/2314 404/412/2315 333/411/2316 +f 407/413/2317 401/415/2318 404/412/2319 +f 408/406/2320 412/417/2321 411/414/2322 +f 410/407/2323 411/414/2324 407/413/2325 +f 411/414/2326 409/416/2327 401/415/2328 +f 412/417/2329 398/423/2330 409/416/2331 +f 423/419/2332 416/420/2333 415/402/2334 +f 415/402/2335 413/401/2336 423/419/2337 +f 418/421/2338 408/406/2339 400/404/2340 +f 418/421/2341 400/404/2342 415/402/2343 +f 416/420/2344 420/425/2345 419/422/2346 +f 418/421/2347 419/422/2348 412/417/2349 +f 419/422/2350 417/424/2351 398/423/2352 +f 420/425/2353 414/427/2354 417/424/2355 +f 421/418/2356 425/429/2357 424/426/2358 +f 423/419/2359 424/426/2360 420/425/2361 +f 424/426/2362 422/428/2363 414/427/2364 +f 425/429/2365 395/438/2366 422/428/2367 +f 13/431/2368 17/496/2369 428/430/2370 +f 430/432/2371 413/401/2372 397/337/2373 +f 430/432/2374 397/337/2375 427/336/2376 +f 438/434/2377 431/435/2378 430/432/2379 +f 438/434/2380 430/432/2381 428/430/2382 +f 433/436/2383 421/418/2384 413/401/2385 +f 433/436/2386 413/401/2387 430/432/2388 +f 431/435/2389 435/440/2390 434/437/2391 +f 433/436/2392 434/437/2393 425/429/2394 +f 434/437/2395 432/439/2396 395/438/2397 +f 435/440/2398 429/442/2399 432/439/2400 +f 436/433/2401 440/444/2402 439/441/2403 +f 438/434/2404 439/441/2405 435/440/2406 +f 439/441/2407 437/443/2408 429/442/2409 +f 440/444/2410 426/446/2411 437/443/2412 +f 428/430/2413 17/496/2414 21/497/2415 +f 436/433/2416 428/430/2417 1/445/2418 +f 440/444/2419 436/433/2420 1/445/2421 +f 25/498/2422 1/445/2423 428/430/2424 +f 428/430/2425 21/497/2426 25/498/2427 +f 441/448/2428 448/454/2429 447/449/2430 +f 442/452/2431 445/453/2432 444/450/2433 +f 443/451/2434 444/450/2435 329/334/2436 +f 444/450/2437 336/340/2438 265/268/2439 +f 445/453/2440 334/341/2441 336/340/2442 +f 446/447/2443 447/449/2444 332/335/2445 +f 447/449/2446 443/451/2447 326/332/2448 +f 448/454/2449 442/452/2450 443/451/2451 +f 75/457/2452 78/458/2453 450/455/2454 +f 449/456/2455 450/455/2456 445/453/2457 +f 450/455/2458 396/338/2459 334/341/2460 +f 78/458/2461 9/495/2462 396/338/2463 +f 451/262/2464 452/261/2465 448/454/2466 +f 452/261/2467 449/456/2468 442/452/2469 +f 82/459/2470 75/457/2471 449/456/2472 +f 453/461/2473 464/471/2474 463/462/2475 +f 454/465/2476 457/466/2477 456/463/2478 +f 455/464/2479 456/463/2480 247/247/2481 +f 456/463/2482 330/264/2483 6/8/2484 +f 457/466/2485 264/265/2486 330/264/2487 +f 458/469/2488 461/470/2489 460/467/2490 +f 459/468/2491 460/467/2492 259/259/2493 +f 460/467/2494 455/464/2495 240/242/2496 +f 461/470/2497 454/465/2498 455/464/2499 +f 462/460/2500 463/462/2501 262/260/2502 +f 463/462/2503 459/468/2504 256/258/2505 +f 464/471/2506 458/469/2507 459/468/2508 +f 224/474/2509 227/479/2510 470/472/2511 +f 465/477/2512 468/478/2513 467/475/2514 +f 466/476/2515 467/475/2516 457/466/2517 +f 467/475/2518 446/447/2519 264/265/2520 +f 468/478/2521 441/448/2522 446/447/2523 +f 469/473/2524 470/472/2525 468/478/2526 +f 470/472/2527 451/262/2528 441/448/2529 +f 227/479/2530 5/263/2531 451/262/2532 +f 471/481/2533 478/487/2534 477/482/2535 +f 472/485/2536 475/486/2537 474/483/2538 +f 473/484/2539 474/483/2540 461/470/2541 +f 474/483/2542 466/476/2543 454/465/2544 +f 475/486/2545 465/477/2546 466/476/2547 +f 476/480/2548 477/482/2549 464/471/2550 +f 477/482/2551 473/484/2552 458/469/2553 +f 478/487/2554 472/485/2555 473/484/2556 +f 230/490/2557 233/491/2558 480/488/2559 +f 479/489/2560 480/488/2561 475/486/2562 +f 480/488/2563 469/473/2564 465/477/2565 +f 233/491/2566 224/474/2567 469/473/2568 +f 481/1/2569 482/3/2570 478/487/2571 +f 482/3/2572 479/489/2573 472/485/2574 +f 237/492/2575 230/490/2576 479/489/2577 diff --git a/src/assets/lamp.obj b/src/assets/lamp.obj new file mode 100644 index 0000000..4d0a85c --- /dev/null +++ b/src/assets/lamp.obj @@ -0,0 +1,1211 @@ +# This file uses centimeters as units for non-parametric coordinates. + +mtllib lamp.mtl +g default +v 2.656471 15.855046 5.780191 +v 2.535695 15.855046 5.017639 +v 2.656471 15.855046 4.255087 +v 3.006978 15.855046 3.567179 +v 3.552904 15.855046 3.021253 +v 4.240812 15.855046 2.670746 +v 5.003365 15.855046 2.549970 +v 5.765916 15.855046 2.670746 +v 6.453824 15.855046 3.021253 +v 6.999750 15.855046 3.567179 +v 7.350257 15.855046 4.255087 +v 7.471033 15.855046 5.017639 +v 7.350257 15.855046 5.780191 +v 6.999750 15.855046 6.468100 +v 6.453824 15.855046 7.014026 +v 5.765916 15.855046 7.364532 +v 5.003365 15.855046 7.485309 +v 4.240812 15.855046 7.364532 +v 3.552904 15.855046 7.014026 +v 3.006978 15.855046 6.468100 +v 3.327012 19.818167 5.562319 +v 3.240743 19.818167 5.017639 +v 3.327012 19.818167 4.472960 +v 3.577374 19.818167 3.981596 +v 3.967321 19.818167 3.591650 +v 4.458684 19.818167 3.341287 +v 5.003365 19.818167 3.255018 +v 5.548044 19.818167 3.341287 +v 6.039407 19.818167 3.591650 +v 6.429354 19.818167 3.981596 +v 6.679716 19.818167 4.472960 +v 6.765985 19.818167 5.017639 +v 6.679716 19.818167 5.562319 +v 6.429354 19.818167 6.053682 +v 6.039407 19.818167 6.443629 +v 5.548044 19.818167 6.693992 +v 5.003365 19.818167 6.780261 +v 4.458684 19.818167 6.693992 +v 3.967321 19.818167 6.443629 +v 3.577374 19.818167 6.053682 +v 5.003365 19.818167 5.017639 +v 5.003365 15.855044 5.017639 +v 1.159431 0.014822 6.247877 +v 0.961787 0.014822 5.000000 +v 1.159431 0.014822 3.752123 +v 1.733017 0.014822 2.626398 +v 2.626398 0.014822 1.733017 +v 3.752123 0.014822 1.159431 +v 5.000000 0.014822 0.961787 +v 6.247877 0.014822 1.159431 +v 7.373602 0.014822 1.733017 +v 8.266983 0.014822 2.626398 +v 8.840569 0.014822 3.752123 +v 9.038213 0.014822 5.000000 +v 8.840569 0.014822 6.247877 +v 8.266983 0.014822 7.373602 +v 7.373602 0.014822 8.266983 +v 6.247877 0.014822 8.840569 +v 5.000000 0.014822 9.038213 +v 3.752123 0.014822 8.840569 +v 2.626398 0.014822 8.266983 +v 1.733017 0.014822 7.373602 +v 3.736371 -5.387635 5.410578 +v 3.671342 -5.387635 5.000000 +v 3.736371 -5.387635 4.589422 +v 3.925093 -5.387635 4.219035 +v 4.219035 -5.387635 3.925093 +v 4.589422 -5.387635 3.736371 +v 5.000000 -5.387635 3.671342 +v 5.410578 -5.387635 3.736371 +v 5.780965 -5.387635 3.925093 +v 6.074907 -5.387635 4.219035 +v 6.263629 -5.387635 4.589422 +v 6.328658 -5.387635 5.000000 +v 6.263629 -5.387635 5.410578 +v 6.074907 -5.387635 5.780965 +v 5.780965 -5.387635 6.074907 +v 5.410578 -5.387635 6.263629 +v 5.000000 -5.387635 6.328658 +v 4.589422 -5.387635 6.263629 +v 4.219035 -5.387635 6.074907 +v 3.925093 -5.387635 5.780965 +v 3.780450 -5.669678 5.396256 +v 3.717689 -5.669678 5.000000 +v 3.780450 -5.669678 4.603744 +v 3.962589 -5.669678 4.246277 +v 4.246277 -5.669678 3.962589 +v 4.603744 -5.669678 3.780450 +v 5.000000 -5.669678 3.717689 +v 5.396256 -5.669678 3.780450 +v 5.753723 -5.669678 3.962589 +v 6.037411 -5.669678 4.246277 +v 6.219550 -5.669678 4.603744 +v 6.282311 -5.669678 5.000000 +v 6.219550 -5.669678 5.396256 +v 6.037411 -5.669678 5.753723 +v 5.753723 -5.669678 6.037411 +v 5.396256 -5.669678 6.219550 +v 5.000000 -5.669678 6.282311 +v 4.603744 -5.669678 6.219550 +v 4.246277 -5.669678 6.037411 +v 3.962589 -5.669678 5.753723 +v 1.125356 -11.094143 6.258948 +v 0.925958 -11.094143 5.000000 +v 1.125356 -11.094143 3.741052 +v 1.704031 -11.094143 2.605338 +v 2.605338 -11.094143 1.704031 +v 3.741052 -11.094143 1.125356 +v 5.000000 -11.094143 0.925958 +v 6.258948 -11.094143 1.125356 +v 7.394662 -11.094143 1.704031 +v 8.295969 -11.094143 2.605338 +v 8.874644 -11.094143 3.741052 +v 9.074041 -11.094143 5.000000 +v 8.874644 -11.094143 6.258948 +v 8.295969 -11.094143 7.394662 +v 7.394662 -11.094143 8.295969 +v 6.258948 -11.094143 8.874644 +v 5.000000 -11.094143 9.074041 +v 3.741052 -11.094143 8.874644 +v 2.605338 -11.094143 8.295969 +v 1.704031 -11.094143 7.394662 +v 5.000000 0.014822 5.000000 +v 5.000000 -11.094146 5.000000 +vt 0.000000 -1.000000 +vt 1.000000 -1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 2.000000 +vt 0.000000 2.000000 +vt 1.000000 3.000000 +vt 0.000000 3.000000 +vt 1.000000 4.000000 +vt 0.000000 4.000000 +vt 1.000000 5.000000 +vt 0.000000 5.000000 +vt 1.000000 6.000000 +vt 0.000000 6.000000 +vt 1.000000 7.000000 +vt 0.000000 7.000000 +vt 1.000000 8.000000 +vt 0.000000 8.000000 +vt 1.000000 9.000000 +vt 0.000000 9.000000 +vt 1.000000 10.000000 +vt 0.000000 10.000000 +vt 1.000000 11.000000 +vt 0.000000 11.000000 +vt 1.000000 12.000000 +vt 0.000000 12.000000 +vt 1.000000 13.000000 +vt 0.000000 13.000000 +vt 1.000000 14.000000 +vt 0.000000 14.000000 +vt 1.000000 15.000000 +vt 0.000000 15.000000 +vt 1.000000 16.000000 +vt 0.000000 16.000000 +vt 1.000000 17.000000 +vt 0.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 -1.000000 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.333333 -1.000000 +vt 0.000000 1.000000 +vt 0.333333 1.000000 +vt 0.000000 2.000000 +vt 0.333333 2.000000 +vt 0.000000 3.000000 +vt 0.333333 3.000000 +vt 0.000000 4.000000 +vt 0.333333 4.000000 +vt 0.000000 5.000000 +vt 0.333333 5.000000 +vt 0.000000 6.000000 +vt 0.333333 6.000000 +vt 0.000000 7.000000 +vt 0.333333 7.000000 +vt 0.000000 8.000000 +vt 0.333333 8.000000 +vt 0.000000 9.000000 +vt 0.333333 9.000000 +vt 0.000000 10.000000 +vt 0.333333 10.000000 +vt 0.000000 11.000000 +vt 0.333333 11.000000 +vt 0.000000 12.000000 +vt 0.333333 12.000000 +vt 0.000000 13.000000 +vt 0.333333 13.000000 +vt 0.000000 14.000000 +vt 0.333333 14.000000 +vt 0.000000 15.000000 +vt 0.333333 15.000000 +vt 0.000000 16.000000 +vt 0.333333 16.000000 +vt 0.000000 17.000000 +vt 0.333333 17.000000 +vt 0.000000 18.000000 +vt 0.333333 18.000000 +vt 0.666667 0.000000 +vt 0.666667 -1.000000 +vt 0.666667 1.000000 +vt 0.666667 2.000000 +vt 0.666667 3.000000 +vt 0.666667 4.000000 +vt 0.666667 5.000000 +vt 0.666667 6.000000 +vt 0.666667 7.000000 +vt 0.666667 8.000000 +vt 0.666667 9.000000 +vt 0.666667 10.000000 +vt 0.666667 11.000000 +vt 0.666667 12.000000 +vt 0.666667 13.000000 +vt 0.666667 14.000000 +vt 0.666667 15.000000 +vt 0.666667 16.000000 +vt 0.666667 17.000000 +vt 0.666667 18.000000 +vt 1.000000 0.000000 +vt 1.000000 -1.000000 +vt 1.000000 1.000000 +vt 1.000000 2.000000 +vt 1.000000 3.000000 +vt 1.000000 4.000000 +vt 1.000000 5.000000 +vt 1.000000 6.000000 +vt 1.000000 7.000000 +vt 1.000000 8.000000 +vt 1.000000 9.000000 +vt 1.000000 10.000000 +vt 1.000000 11.000000 +vt 1.000000 12.000000 +vt 1.000000 13.000000 +vt 1.000000 14.000000 +vt 1.000000 15.000000 +vt 1.000000 16.000000 +vt 1.000000 17.000000 +vt 1.000000 18.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.972785 0.173061 0.154074 +vn -0.984541 0.175152 0.000000 +vn -0.984541 0.175152 0.000000 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.936355 0.175152 -0.304240 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.796511 0.175152 -0.578699 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.578699 0.175152 -0.796511 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn -0.304240 0.175152 -0.936355 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.000000 0.175152 -0.984541 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.304240 0.175152 -0.936355 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.578699 0.175152 -0.796511 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.796511 0.175152 -0.578699 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.936355 0.175152 -0.304240 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.984541 0.175152 0.000000 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.936355 0.175152 0.304240 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.796511 0.175152 0.578699 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.578699 0.175152 0.796511 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.304240 0.175152 0.936355 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn 0.000000 0.175152 0.984541 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.304240 0.175152 0.936355 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.578699 0.175152 0.796511 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.796511 0.175152 0.578699 +vn -0.936355 0.175152 0.304240 +vn -0.936355 0.175152 0.304240 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 -0.000004 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 -0.000002 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000004 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000000 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.000001 -1.000000 0.000002 +vn -0.850126 -0.448316 0.276223 +vn -0.893876 -0.448315 0.000000 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 0.277092 +vn -0.893876 -0.448315 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.852801 -0.442663 -0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.850126 -0.448316 -0.276223 +vn -0.723160 -0.448316 -0.525407 +vn -0.725436 -0.442663 -0.527060 +vn -0.852801 -0.442663 -0.277092 +vn -0.723160 -0.448316 -0.525407 +vn -0.525407 -0.448316 -0.723160 +vn -0.527060 -0.442663 -0.725436 +vn -0.725436 -0.442663 -0.527060 +vn -0.525407 -0.448316 -0.723160 +vn -0.276223 -0.448316 -0.850126 +vn -0.277092 -0.442663 -0.852801 +vn -0.527060 -0.442663 -0.725436 +vn -0.276223 -0.448316 -0.850126 +vn 0.000000 -0.448316 -0.893875 +vn 0.000000 -0.442663 -0.896688 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.448316 -0.893875 +vn 0.276223 -0.448316 -0.850126 +vn 0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.276223 -0.448316 -0.850126 +vn 0.525407 -0.448316 -0.723160 +vn 0.527060 -0.442663 -0.725436 +vn 0.277092 -0.442663 -0.852801 +vn 0.525407 -0.448316 -0.723160 +vn 0.723160 -0.448316 -0.525407 +vn 0.725436 -0.442663 -0.527060 +vn 0.527060 -0.442663 -0.725436 +vn 0.723160 -0.448316 -0.525407 +vn 0.850126 -0.448316 -0.276223 +vn 0.852801 -0.442663 -0.277092 +vn 0.725436 -0.442663 -0.527060 +vn 0.850126 -0.448316 -0.276223 +vn 0.893876 -0.448315 0.000000 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 -0.277092 +vn 0.893876 -0.448315 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.852801 -0.442663 0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.850126 -0.448316 0.276223 +vn 0.723160 -0.448316 0.525407 +vn 0.725436 -0.442663 0.527060 +vn 0.852801 -0.442663 0.277092 +vn 0.723160 -0.448316 0.525407 +vn 0.525407 -0.448316 0.723160 +vn 0.527060 -0.442663 0.725436 +vn 0.725436 -0.442663 0.527060 +vn 0.525407 -0.448316 0.723160 +vn 0.276223 -0.448316 0.850126 +vn 0.277092 -0.442663 0.852801 +vn 0.527060 -0.442663 0.725436 +vn 0.276223 -0.448316 0.850126 +vn 0.000000 -0.448316 0.893875 +vn 0.000000 -0.442663 0.896688 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.448316 0.893875 +vn -0.276223 -0.448316 0.850126 +vn -0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn -0.276223 -0.448316 0.850126 +vn -0.525407 -0.448316 0.723160 +vn -0.527060 -0.442663 0.725436 +vn -0.277092 -0.442663 0.852801 +vn -0.525407 -0.448316 0.723160 +vn -0.723160 -0.448316 0.525407 +vn -0.725436 -0.442663 0.527060 +vn -0.527060 -0.442663 0.725436 +vn -0.723160 -0.448316 0.525407 +vn -0.850126 -0.448316 0.276223 +vn -0.852801 -0.442663 0.277092 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.896688 -0.442663 0.000000 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 0.276577 +vn -0.896688 -0.442663 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.851218 0.446020 -0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.852801 -0.442663 -0.277092 +vn -0.725436 -0.442663 -0.527060 +vn -0.724089 0.446020 -0.526081 +vn -0.851218 0.446020 -0.276577 +vn -0.725436 -0.442663 -0.527060 +vn -0.527060 -0.442663 -0.725436 +vn -0.526081 0.446020 -0.724089 +vn -0.724089 0.446020 -0.526081 +vn -0.527060 -0.442663 -0.725436 +vn -0.277092 -0.442663 -0.852801 +vn -0.276577 0.446020 -0.851218 +vn -0.526081 0.446020 -0.724089 +vn -0.277092 -0.442663 -0.852801 +vn 0.000000 -0.442663 -0.896688 +vn 0.000000 0.446020 -0.895023 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 -0.442663 -0.896688 +vn 0.277092 -0.442663 -0.852801 +vn 0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.277092 -0.442663 -0.852801 +vn 0.527060 -0.442663 -0.725436 +vn 0.526081 0.446020 -0.724089 +vn 0.276577 0.446020 -0.851218 +vn 0.527060 -0.442663 -0.725436 +vn 0.725436 -0.442663 -0.527060 +vn 0.724089 0.446020 -0.526081 +vn 0.526081 0.446020 -0.724089 +vn 0.725436 -0.442663 -0.527060 +vn 0.852801 -0.442663 -0.277092 +vn 0.851218 0.446020 -0.276577 +vn 0.724089 0.446020 -0.526081 +vn 0.852801 -0.442663 -0.277092 +vn 0.896688 -0.442663 0.000000 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 -0.276577 +vn 0.896688 -0.442663 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.851218 0.446020 0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.852801 -0.442663 0.277092 +vn 0.725436 -0.442663 0.527060 +vn 0.724089 0.446020 0.526081 +vn 0.851218 0.446020 0.276577 +vn 0.725436 -0.442663 0.527060 +vn 0.527060 -0.442663 0.725436 +vn 0.526081 0.446020 0.724089 +vn 0.724089 0.446020 0.526081 +vn 0.527060 -0.442663 0.725436 +vn 0.277092 -0.442663 0.852801 +vn 0.276577 0.446020 0.851218 +vn 0.526081 0.446020 0.724089 +vn 0.277092 -0.442663 0.852801 +vn 0.000000 -0.442663 0.896688 +vn 0.000000 0.446020 0.895023 +vn 0.276577 0.446020 0.851218 +vn 0.000000 -0.442663 0.896688 +vn -0.277092 -0.442663 0.852801 +vn -0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn -0.277092 -0.442663 0.852801 +vn -0.527060 -0.442663 0.725436 +vn -0.526081 0.446020 0.724089 +vn -0.276577 0.446020 0.851218 +vn -0.527060 -0.442663 0.725436 +vn -0.725436 -0.442663 0.527060 +vn -0.724089 0.446020 0.526081 +vn -0.526081 0.446020 0.724089 +vn -0.725436 -0.442663 0.527060 +vn -0.852801 -0.442663 0.277092 +vn -0.851218 0.446020 0.276577 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.895023 0.446020 0.000000 +vn -0.889154 0.457608 0.000000 +vn -0.845636 0.457608 0.274764 +vn -0.895023 0.446020 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.845636 0.457608 -0.274764 +vn -0.889154 0.457608 0.000000 +vn -0.851218 0.446020 -0.276577 +vn -0.724089 0.446020 -0.526081 +vn -0.719341 0.457608 -0.522631 +vn -0.845636 0.457608 -0.274764 +vn -0.724089 0.446020 -0.526081 +vn -0.526081 0.446020 -0.724089 +vn -0.522632 0.457608 -0.719341 +vn -0.719341 0.457608 -0.522631 +vn -0.526081 0.446020 -0.724089 +vn -0.276577 0.446020 -0.851218 +vn -0.274764 0.457608 -0.845636 +vn -0.522632 0.457608 -0.719341 +vn -0.276577 0.446020 -0.851218 +vn 0.000000 0.446020 -0.895023 +vn 0.000000 0.457608 -0.889154 +vn -0.274764 0.457608 -0.845636 +vn 0.000000 0.446020 -0.895023 +vn 0.276577 0.446020 -0.851218 +vn 0.274764 0.457608 -0.845636 +vn 0.000000 0.457608 -0.889154 +vn 0.276577 0.446020 -0.851218 +vn 0.526081 0.446020 -0.724089 +vn 0.522632 0.457608 -0.719341 +vn 0.274764 0.457608 -0.845636 +vn 0.526081 0.446020 -0.724089 +vn 0.724089 0.446020 -0.526081 +vn 0.719341 0.457608 -0.522631 +vn 0.522632 0.457608 -0.719341 +vn 0.724089 0.446020 -0.526081 +vn 0.851218 0.446020 -0.276577 +vn 0.845636 0.457608 -0.274764 +vn 0.719341 0.457608 -0.522631 +vn 0.851218 0.446020 -0.276577 +vn 0.895023 0.446020 0.000000 +vn 0.889154 0.457608 0.000000 +vn 0.845636 0.457608 -0.274764 +vn 0.895023 0.446020 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.845636 0.457608 0.274764 +vn 0.889154 0.457608 0.000000 +vn 0.851218 0.446020 0.276577 +vn 0.724089 0.446020 0.526081 +vn 0.719341 0.457608 0.522631 +vn 0.845636 0.457608 0.274764 +vn 0.724089 0.446020 0.526081 +vn 0.526081 0.446020 0.724089 +vn 0.522632 0.457608 0.719341 +vn 0.719341 0.457608 0.522631 +vn 0.526081 0.446020 0.724089 +vn 0.276577 0.446020 0.851218 +vn 0.274764 0.457608 0.845636 +vn 0.522632 0.457608 0.719341 +vn 0.276577 0.446020 0.851218 +vn 0.000000 0.446020 0.895023 +vn 0.000000 0.457608 0.889154 +vn 0.274764 0.457608 0.845636 +vn 0.000000 0.446020 0.895023 +vn -0.276577 0.446020 0.851218 +vn -0.274764 0.457608 0.845636 +vn 0.000000 0.457608 0.889154 +vn -0.276577 0.446020 0.851218 +vn -0.526081 0.446020 0.724089 +vn -0.522632 0.457608 0.719341 +vn -0.274764 0.457608 0.845636 +vn -0.526081 0.446020 0.724089 +vn -0.724089 0.446020 0.526081 +vn -0.719341 0.457608 0.522631 +vn -0.522632 0.457608 0.719341 +vn -0.724089 0.446020 0.526081 +vn -0.851218 0.446020 0.276577 +vn -0.845636 0.457608 0.274764 +vn -0.719341 0.457608 0.522631 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000000 1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 -0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn -0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 -0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000001 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000001 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000000 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000000 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +vn -0.000001 -1.000000 0.000001 +s off +g polySurface1 +usemtl initialShadingGroup +f 1/1/1 21/2/2 22/3/3 2/4/4 +f 2/4/5 22/3/6 23/5/7 3/6/8 +f 3/6/9 23/5/10 24/7/11 4/8/12 +f 4/8/13 24/7/14 25/9/15 5/10/16 +f 5/10/17 25/9/18 26/11/19 6/12/20 +f 6/12/21 26/11/22 27/13/23 7/14/24 +f 7/14/25 27/13/26 28/15/27 8/16/28 +f 8/16/29 28/15/30 29/17/31 9/18/32 +f 9/18/33 29/17/34 30/19/35 10/20/36 +f 10/20/37 30/19/38 31/21/39 11/22/40 +f 11/22/41 31/21/42 32/23/43 12/24/44 +f 12/24/45 32/23/46 33/25/47 13/26/48 +f 13/26/49 33/25/50 34/27/51 14/28/52 +f 14/28/53 34/27/54 35/29/55 15/30/56 +f 15/30/57 35/29/58 36/31/59 16/32/60 +f 16/32/61 36/31/62 37/33/63 17/34/64 +f 17/34/65 37/33/66 38/35/67 18/36/68 +f 18/36/69 38/35/70 39/37/71 19/38/72 +f 19/38/73 39/37/74 40/39/75 20/40/76 +f 20/40/77 40/39/78 21/2/79 1/1/80 +f 22/41/81 21/42/82 41/43/83 +f 23/44/84 22/45/85 41/46/86 +f 24/47/87 23/48/88 41/49/89 +f 25/50/90 24/51/91 41/52/92 +f 26/53/93 25/54/94 41/55/95 +f 27/56/96 26/57/97 41/58/98 +f 28/59/99 27/60/100 41/61/101 +f 29/62/102 28/63/103 41/64/104 +f 30/65/105 29/66/106 41/67/107 +f 31/68/108 30/69/109 41/70/110 +f 32/71/111 31/72/112 41/73/113 +f 33/74/114 32/75/115 41/76/116 +f 34/77/117 33/78/118 41/79/119 +f 35/80/120 34/81/121 41/82/122 +f 36/83/123 35/84/124 41/85/125 +f 37/86/126 36/87/127 41/88/128 +f 38/89/129 37/90/130 41/91/131 +f 39/92/132 38/93/133 41/94/134 +f 40/95/135 39/96/136 41/97/137 +f 21/98/138 40/99/139 41/100/140 +f 1/101/141 2/102/142 42/103/143 +f 2/104/144 3/105/145 42/106/146 +f 3/107/147 4/108/148 42/109/149 +f 4/110/150 5/111/151 42/112/152 +f 5/113/153 6/114/154 42/115/155 +f 6/116/156 7/117/157 42/118/158 +f 7/119/159 8/120/160 42/121/161 +f 8/122/162 9/123/163 42/124/164 +f 9/125/165 10/126/166 42/127/167 +f 10/128/168 11/129/169 42/130/170 +f 11/131/171 12/132/172 42/133/173 +f 12/134/174 13/135/175 42/136/176 +f 13/137/177 14/138/178 42/139/179 +f 14/140/180 15/141/181 42/142/182 +f 15/143/183 16/144/184 42/145/185 +f 16/146/186 17/147/187 42/148/188 +f 17/149/189 18/150/190 42/151/191 +f 18/152/192 19/153/193 42/154/194 +f 19/155/195 20/156/196 42/157/197 +f 20/158/198 1/159/199 42/160/200 +f 43/161/201 44/162/202 64/163/203 63/164/204 +f 44/162/205 45/165/206 65/166/207 64/163/208 +f 45/165/209 46/167/210 66/168/211 65/166/212 +f 46/167/213 47/169/214 67/170/215 66/168/216 +f 47/169/217 48/171/218 68/172/219 67/170/220 +f 48/171/221 49/173/222 69/174/223 68/172/224 +f 49/173/225 50/175/226 70/176/227 69/174/228 +f 50/175/229 51/177/230 71/178/231 70/176/232 +f 51/177/233 52/179/234 72/180/235 71/178/236 +f 52/179/237 53/181/238 73/182/239 72/180/240 +f 53/181/241 54/183/242 74/184/243 73/182/244 +f 54/183/245 55/185/246 75/186/247 74/184/248 +f 55/185/249 56/187/250 76/188/251 75/186/252 +f 56/187/253 57/189/254 77/190/255 76/188/256 +f 57/189/257 58/191/258 78/192/259 77/190/260 +f 58/191/261 59/193/262 79/194/263 78/192/264 +f 59/193/265 60/195/266 80/196/267 79/194/268 +f 60/195/269 61/197/270 81/198/271 80/196/272 +f 61/197/273 62/199/274 82/200/275 81/198/276 +f 62/199/277 43/161/278 63/164/279 82/200/280 +f 63/164/281 64/163/282 84/201/283 83/202/284 +f 64/163/285 65/166/286 85/203/287 84/201/288 +f 65/166/289 66/168/290 86/204/291 85/203/292 +f 66/168/293 67/170/294 87/205/295 86/204/296 +f 67/170/297 68/172/298 88/206/299 87/205/300 +f 68/172/301 69/174/302 89/207/303 88/206/304 +f 69/174/305 70/176/306 90/208/307 89/207/308 +f 70/176/309 71/178/310 91/209/311 90/208/312 +f 71/178/313 72/180/314 92/210/315 91/209/316 +f 72/180/317 73/182/318 93/211/319 92/210/320 +f 73/182/321 74/184/322 94/212/323 93/211/324 +f 74/184/325 75/186/326 95/213/327 94/212/328 +f 75/186/329 76/188/330 96/214/331 95/213/332 +f 76/188/333 77/190/334 97/215/335 96/214/336 +f 77/190/337 78/192/338 98/216/339 97/215/340 +f 78/192/341 79/194/342 99/217/343 98/216/344 +f 79/194/345 80/196/346 100/218/347 99/217/348 +f 80/196/349 81/198/350 101/219/351 100/218/352 +f 81/198/353 82/200/354 102/220/355 101/219/356 +f 82/200/357 63/164/358 83/202/359 102/220/360 +f 83/202/361 84/201/362 104/221/363 103/222/364 +f 84/201/365 85/203/366 105/223/367 104/221/368 +f 85/203/369 86/204/370 106/224/371 105/223/372 +f 86/204/373 87/205/374 107/225/375 106/224/376 +f 87/205/377 88/206/378 108/226/379 107/225/380 +f 88/206/381 89/207/382 109/227/383 108/226/384 +f 89/207/385 90/208/386 110/228/387 109/227/388 +f 90/208/389 91/209/390 111/229/391 110/228/392 +f 91/209/393 92/210/394 112/230/395 111/229/396 +f 92/210/397 93/211/398 113/231/399 112/230/400 +f 93/211/401 94/212/402 114/232/403 113/231/404 +f 94/212/405 95/213/406 115/233/407 114/232/408 +f 95/213/409 96/214/410 116/234/411 115/233/412 +f 96/214/413 97/215/414 117/235/415 116/234/416 +f 97/215/417 98/216/418 118/236/419 117/235/420 +f 98/216/421 99/217/422 119/237/423 118/236/424 +f 99/217/425 100/218/426 120/238/427 119/237/428 +f 100/218/429 101/219/430 121/239/431 120/238/432 +f 101/219/433 102/220/434 122/240/435 121/239/436 +f 102/220/437 83/202/438 103/222/439 122/240/440 +f 44/241/441 43/242/442 123/243/443 +f 45/244/444 44/245/445 123/246/446 +f 46/247/447 45/248/448 123/249/449 +f 47/250/450 46/251/451 123/252/452 +f 48/253/453 47/254/454 123/255/455 +f 49/256/456 48/257/457 123/258/458 +f 50/259/459 49/260/460 123/261/461 +f 51/262/462 50/263/463 123/264/464 +f 52/265/465 51/266/466 123/267/467 +f 53/268/468 52/269/469 123/270/470 +f 54/271/471 53/272/472 123/273/473 +f 55/274/474 54/275/475 123/276/476 +f 56/277/477 55/278/478 123/279/479 +f 57/280/480 56/281/481 123/282/482 +f 58/283/483 57/284/484 123/285/485 +f 59/286/486 58/287/487 123/288/488 +f 60/289/489 59/290/490 123/291/491 +f 61/292/492 60/293/493 123/294/494 +f 62/295/495 61/296/496 123/297/497 +f 43/298/498 62/299/499 123/300/500 +f 103/301/501 104/302/502 124/303/503 +f 104/304/504 105/305/505 124/306/506 +f 105/307/507 106/308/508 124/309/509 +f 106/310/510 107/311/511 124/312/512 +f 107/313/513 108/314/514 124/315/515 +f 108/316/516 109/317/517 124/318/518 +f 109/319/519 110/320/520 124/321/521 +f 110/322/522 111/323/523 124/324/524 +f 111/325/525 112/326/526 124/327/527 +f 112/328/528 113/329/529 124/330/530 +f 113/331/531 114/332/532 124/333/533 +f 114/334/534 115/335/535 124/336/536 +f 115/337/537 116/338/538 124/339/539 +f 116/340/540 117/341/541 124/342/542 +f 117/343/543 118/344/544 124/345/545 +f 118/346/546 119/347/547 124/348/548 +f 119/349/549 120/350/550 124/351/551 +f 120/352/552 121/353/553 124/354/554 +f 121/355/555 122/356/556 124/357/557 +f 122/358/558 103/359/559 124/360/560 From 3502dcf07af755cea86e03cf5b202a2a2076e934 Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Mon, 27 Feb 2017 21:09:20 -0500 Subject: [PATCH 13/14] camera position --- README.md | 4 +--- src/main.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bd29874..bbf47fc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ Lava Lamp Shaders: -The lava is shaded with GLSL matcap shader, using a lit sphere texture. The color is smoothed with a cosine color mapping. I modeled the lamp in Maya. - -Since watching the lava lamp / metaballs and changing colors are so soothing, I decided to create a website with inspiration quotes (A new one each time the web page loads). \ No newline at end of file +The lava is shaded with GLSL matcap shader, using a lit sphere texture. The color is smoothed with a cosine color mapping. I modeled the lamp in Maya. \ No newline at end of file diff --git a/src/main.js b/src/main.js index 0885ac8..b84d799 100644 --- a/src/main.js +++ b/src/main.js @@ -169,7 +169,7 @@ function onUpdate(framework) { function setupCamera(camera) { // set camera position camera.position.set(25, 10, 25); - camera.lookAt(new THREE.Vector3(8,0,-5)); + camera.lookAt(new THREE.Vector3(1,0,1)); } function setupLights(scene) { From 23b59f0675cd736ea016e92c9ab1963edbfddcab Mon Sep 17 00:00:00 2001 From: sarahforcier Date: Mon, 27 Feb 2017 21:10:59 -0500 Subject: [PATCH 14/14] deploy take 2 --- build/bundle.js | 2 +- build/bundle.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index b8fc70e..52c365f 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -233,7 +233,7 @@ function setupCamera(camera) { // set camera position camera.position.set(25, 10, 25); - camera.lookAt(new THREE.Vector3(8, 0, -5)); + camera.lookAt(new THREE.Vector3(1, 0, 1)); } function setupLights(scene) { diff --git a/build/bundle.js.map b/build/bundle.js.map index 0cd8cd6..a5f883f 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap ffceba391a39c929c245","webpack:///./src/main.js","webpack:///./src/textures.js","webpack:///./~/three/build/three.js","webpack:///./src/assets/silver.bmp","webpack:///./src/framework.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/three-orbit-controls/index.js","webpack:///./src/marching_cube_LUT.js","webpack:///./src/marching_cubes.js","webpack:///./src/metaball.js","webpack:///./src/inspect_point.js","webpack:///./src/shaders/lava-vert.glsl","webpack:///./src/shaders/lava-frag.glsl","webpack:///./index.html","webpack:///./~/three-obj-loader/dist/index.js","webpack:///./src/shaders/glass-vert.glsl","webpack:///./src/shaders/glass-frag.glsl","webpack:///./src/shaders/metal-vert.glsl","webpack:///./src/shaders/metal-frag.glsl","webpack:///./src/assets/glass.obj","webpack:///./src/assets/lamp.obj"],"names":["require","THREE","OBJLoader","DEFAULT_VISUAL_DEBUG","DEFAULT_ISO_LEVEL","DEFAULT_GRID_RES","DEFAULT_GRID_WIDTH","DEFAULT_GRID_HEIGHT","DEFAULT_GRID_DEPTH","DEFAULT_NUM_METABALLS","DEFAULT_MIN_RADIUS","DEFAULT_MAX_RADIUS","DEFAULT_MAX_SPEEDX","DEFAULT_MAX_SPEEDY","options","lightColor","lightIntensity","ambient","albedo","loaded","red","Color","green","glassGeo","lampGeo","g_mat","uniforms","u_albedo","type","value","u_ambient","u_lightCol","u_lightIntensity","vertexShader","fragmentShader","m_mat","GLASS_MAT","MeshLambertMaterial","color","emissive","transparent","opacity","METAL_MAT","MeshPhongMaterial","App","marchingCubes","undefined","config","visualDebug","isolevel","gridRes","gridWidth","gridHeight","gridDepth","gridCellWidth","gridCellHeight","gridCellDepth","numMetaballs","minRadius","maxRadius","maxSpeedX","maxSpeedY","maxSpeedZ","camera","scene","renderer","isPaused","onLoad","framework","gui","stats","setClearColor","objLoader","obj","load","children","geometry","glass","Mesh","translateX","translateZ","add","lamp","setupCamera","setupLights","setupScene","setupGUI","cosine","a","b","c","d","t","Math","cos","PI","onUpdate","date","Date","sec","getSeconds","r","g","set","update","position","lookAt","Vector3","directionalLight","DirectionalLight","setHSL","multiplyScalar","step","onChange","reset","init","silverTexture","Promise","resolve","reject","TextureLoader","texture","OrbitControls","callback","setMode","domElement","style","left","top","document","body","appendChild","GUI","window","addEventListener","Scene","PerspectiveCamera","innerWidth","innerHeight","WebGLRenderer","antialias","alpha","setPixelRatio","devicePixelRatio","setSize","controls","enableDamping","enableZoom","target","rotateSpeed","zoomSpeed","panSpeed","hasMoved","aspect","updateProjectionMatrix","tick","begin","render","end","requestAnimationFrame","EDGE_TABLE","Int32Array","TRI_TABLE","VISUAL_DEBUG","episolon","balls","l_mat","LAVA_MAT","ShaderMaterial","LAMBERT_WHITE","LAMBERT_GREEN","MeshBasicMaterial","WIREFRAME_MAT","LineBasicMaterial","linewidth","sample","point","isovalue","i","length","radius","distanceTo","pos","MarchingCubes","origin","halfCellWidth","halfCellHeight","halfCellDepth","res","res2","res3","voxels","showSpheres","showGrid","then","material","setupCells","setupMetaballs","makeMesh","remove","mesh","i1","i3x","i3y","i3z","i3","x","y","z","i1toi3","i3toPos","voxel","Voxel","push","wireframe","vx","vy","vz","vel","matLambertWhite","maxRadiusTRippled","maxRadiusDoubled","random","neg","ball","forEach","center","corners","show","hide","updateLabel","clearLabel","updateMesh","geo","Geometry","dynamic","vertices","faces","count","vox_count","vANDn","polygonize","j","vertPositions","normals","k","vertNormals","Face3","verticesNeedUpdate","normalsNeedUpdate","elementsNeedUpdate","computeFaceNormals","makeInspectPoints","halfGridCellWidth","halfGridCellHeight","halfGridCellDepth","positions","Float32Array","indices","Uint16Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","BoxBufferGeometry","w","h","visible","posA","posB","lerpPos","lerpVectors","edges","points","vertexLerp","x0","x1","y0","y1","z0","z1","n","normalize","vertexList","normalList","faceList","corner","allVert","edgePoints","tri","vertex","getNormal","SPHERE_GEO","SphereBufferGeometry","Metaball","radius2","debug","scale","velocity","copy","POINT_MATERIAL","PointsMaterial","size","sizeAttenuation","InspectPoint","label","makeLabel","createElement","width","height","userSelect","cursor","fontSize","pointerEvents","screenPos","clone","project","innerHTML","toFixed"],"mappings":"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;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,0BAA0B;;AAEhE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2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AEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;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A0B,0BAA0B,wBAAwB,8CAA8C,qCAAqC,wCAAwC,6BAA6B,8CAA8C,swBAAswB,wFAAwF,yGAAyG,0CAA0C,qnBAAqnB,yDAAyD,6IAA6I;;AAEvpE,wEAAuE,8CAA8C,gYAAgY,iTAAiT,+QAA+Q,gEAAgE;;AAErnC,2CAA0C,uBAAuB,sIAAsI,sGAAsG,sCAAsC;;AAEnV,0CAAyC,kJAAkJ,iDAAiD,kKAAkK;;AAE9Y,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,8KAA8K,wKAAwK,mCAAmC,gJAAgJ;;AAEtkB,2CAA0C,yKAAyK,+EAA+E,GAAG;;AAErS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,0DAAyD;AACzD,0CAAyC;AACzC,0CAAyC;;AAEzC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,eAAc,YAAY;;AAE1B;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;;AAE1B,UAAS,cAAc;AACvB,mBAAkB,mCAAmC;;AAErD,kBAAiB,cAAc;AAC/B,eAAc,cAAc;;AAE5B,aAAY,cAAc;AAC1B,iBAAgB,aAAa;AAC7B,mBAAkB,aAAa;AAC/B,sBAAqB;;AAErB,IAAG;;AAEH;;AAEA,YAAW,cAAc;AACzB,qBAAoB;;AAEpB,IAAG;;AAEH;;AAEA,eAAc,cAAc;AAC5B,wBAAuB;;AAEvB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,cAAa,cAAc;AAC3B,gBAAe;;AAEf,IAAG;;AAEH;;AAEA,gBAAe,cAAc;AAC7B,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,sBAAqB,cAAc;AACnC,wBAAuB,WAAW;AAClC,uBAAsB;;AAEtB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,iBAAgB,iBAAiB;AACjC,cAAa,WAAW;AACxB,aAAY,cAAc;AAC1B,eAAc;;AAEd,IAAG;;AAEH;;AAEA,wBAAuB,YAAY;;AAEnC,wBAAuB;AACvB,kBAAiB;AACjB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,2BAA0B,YAAY;AACtC,8BAA6B,YAAY;;AAEzC,iBAAgB;AAChB,cAAa;AACb,iBAAgB;AAChB,kBAAiB;AACjB,iBAAgB;AAChB,gBAAe;AACf,oBAAmB;AACnB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,oBAAmB,YAAY;AAC/B,uBAAsB,YAAY;;AAElC,kBAAiB;AACjB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb,iBAAgB;;AAEhB,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,qBAAoB,YAAY;AAChC,wBAAuB,YAAY;;AAEnC,uBAAsB;AACtB,kBAAiB;AACjB,iBAAgB;AAChB;AACA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;AAC1B,WAAU,aAAa;AACvB,YAAW,aAAa;AACxB,UAAS,cAAc;AACvB,mBAAkB;;AAElB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB,+BAA+B;AAChD,kBAAiB,+BAA+B;AAChD,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB,+BAA+B;AAChD,kBAAiB,aAAa;AAC9B,kBAAiB,WAAW;AAC5B,yBAAwB,WAAW;AACnC;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA,kBAAiB,WAAW;AAC5B,kBAAiB,WAAW;AAC5B,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,gBAAe;;AAEf,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,aAAY,cAAc;AAC1B,aAAY,aAAa;AACzB,eAAc;AACd,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,cAAc;AAC9B,aAAY;AACZ,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,gBAAe;;AAEf,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,iBAAgB,WAAW;AAC3B,0BAAyB;AACzB;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mCAAkC;;AAElC,mCAAkC;AAClC,0BAAyB;AACzB,8BAA6B;;AAE7B,sCAAqC;;AAErC,+BAA8B;AAC9B,yBAAwB;;AAExB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB,iBAAgB;;AAEhB,4BAA2B;;AAE3B,gCAA+B;;AAE/B,uEAAsE;AACtE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;;AAElE,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD,6EAA4E;AAC5E,6EAA4E;;AAE5E,SAAQ;;AAER,4FAA2F;;AAE3F,QAAO;;AAEP;;AAEA;;AAEA,mCAAkC;;AAElC,6BAA4B;AAC5B,6BAA4B;AAC5B,0BAAyB;;AAEzB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB;;AAEA,gCAA+B;;AAE/B,mDAAkD;;AAElD;;AAEA,SAAQ,8BAA8B;;AAEtC,8CAA6C;;AAE7C;;AAEA,SAAQ,OAAO;;AAEf,8CAA6C;AAC7C,4CAA2C;AAC3C,gCAA+B;AAC/B,mCAAkC;;AAElC,SAAQ;;AAER,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;AACA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;;AAGA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sDAAqD;;AAErD,mCAAkC;AAClC,oCAAmC;AACnC,6BAA4B;AAC5B,yBAAwB;AACxB,4BAA2B;AAC3B,2BAA0B;;AAE1B,8BAA6B;AAC7B,wBAAuB;;AAEvB,uBAAsB;;AAEtB,mBAAkB;;AAElB,qCAAoC;;AAEpC,+CAA8C;;AAE9C,4BAA2B;AAC3B,qGAAoG;AACpG,qGAAoG;;AAEpG,0BAAyB;;AAEzB,oEAAmE;AACnE,2CAA0C;AAC1C,wDAAuD;;AAEvD,mCAAkC;;AAElC,OAAM;;AAEN;;AAEA;;AAEA,sDAAqD;;AAErD,yBAAwB;AACxB,4BAA2B;AAC3B,4BAA2B;;AAE3B,0BAAyB;AACzB,4BAA2B;AAC3B,+BAA8B;AAC9B,4BAA2B;AAC3B,2BAA0B;AAC1B,8BAA6B;;AAE7B,uBAAsB;;AAEtB,mBAAkB;;AAElB,4CAA2C;;AAE3C,4CAA2C;;AAE3C,uEAAsE;;AAEtE,2BAA0B;;AAE1B,sDAAqD;AACrD,8BAA6B;;AAE7B,6BAA4B;;AAE5B,0DAAyD;;AAEzD,SAAQ,OAAO;;AAEf,qCAAoC;AACpC,8EAA6E;AAC7E,wDAAuD;;AAEvD,SAAQ;;AAER,wFAAuF;;AAEvF,QAAO;;AAEP,OAAM;;AAEN;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gCAA+B;AAC/B,gCAA+B;;AAE/B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,yBAAwB;;AAExB;AACA;AACA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA,kBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,2CAA0C;;AAE1C;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB,SAAS;AAC7B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,iBAAiB;;AAEzC,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA,8BAA6B,kBAAkB;;AAE/C;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,iBAAgB,gBAAgB,aAAa,iBAAiB,YAAY,EAAE;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qCAAoC,6EAA6E,GAAG;AACpH,uCAAsC,8CAA8C,GAAG;;AAEvF;;AAEA;AACA;;AAEA,oBAAmB;AACnB,uBAAsB;AACtB,yBAAwB;;AAExB,yBAAwB;AACxB,6BAA4B;AAC5B,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAqC,OAAO;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C,QAAQ;;AAErD;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;;AAEjF;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;;AAEhC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,iCAAgC,YAAY;;AAE5C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,iCAAgC,YAAY;;AAE5C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;;AAEjC;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;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;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA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BAAkB;;AAE/C;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAE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;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AA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ACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA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oBAAoB;;AAEtC,oBAAmB,mBAAmB;;AAEtC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,kBAAkB;;AAEhC,gBAAe,oBAAoB;;AAEnC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,eAAc,iBAAiB;;AAE/B;;AAEA,gBAAe,mBAAmB;;AAElC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;AACA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A;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAE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;AAEhD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0FAAyF,4CAA4C;AACrI;;AAEA;AACA;AACA,8FAA6F,4CAA4C;AACzI;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAE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AEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAuB,oCAAoC;AAC3D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA,QAAO;;AAEP;;AAEA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA,EAAC;AACD;AACA,SAAQ,gBAAgB,SAAS,UAAU,WAAW,WAAW,OAAO,eAAe,MAAM,OAAO,QAAQ,SAAS,UAAU,mBAAmB,gBAAgB,SAAS,uCAAuC,kCAAkC,oCAAoC,+BAA+B,4BAA4B,gBAAgB,0CAA0C,UAAU,gBAAgB,6BAA6B,iCAAiC,qBAAqB,yDAAyD,UAAU,uBAAuB,uCAAuC,kCAAkC,oCAAoC,+BAA+B,SAAS,kBAAkB,iBAAiB,YAAY,eAAe,kBAAkB,sBAAsB,6BAA6B,sBAAsB,MAAM,YAAY,kBAAkB,kBAAkB,kBAAkB,gBAAgB,yBAAyB,aAAa,gBAAgB,eAAe,MAAM,aAAa,OAAO,wCAAwC,mCAAmC,qCAAqC,gCAAgC,oBAAoB,YAAY,YAAY,iBAAiB,gBAAgB,oBAAoB,cAAc,UAAU,oCAAoC,aAAa,eAAe,iBAAiB,mEAAmE,SAAS,gBAAgB,SAAS,QAAQ,WAAW,iBAAiB,YAAY,mBAAmB,eAAe,WAAW,WAAW,UAAU,gBAAgB,uBAAuB,OAAO,WAAW,UAAU,wBAAwB,SAAS,eAAe,YAAY,WAAW,YAAY,iCAAiC,UAAU,cAAc,YAAY,WAAW,UAAU,iBAAiB,eAAe,YAAY,eAAe,eAAe,YAAY,4BAA4B,eAAe,cAAc,eAAe,sGAAsG,eAAe,cAAc,aAAa,kBAAkB,iBAAiB,gBAAgB,WAAW,0CAA0C,cAAc,gBAAgB,UAAU,wBAAwB,qBAAqB,gBAAgB,aAAa,sBAAsB,YAAY,aAAa,eAAe,iBAAiB,oBAAoB,aAAa,WAAW,8BAA8B,eAAe,SAAS,YAAY,kCAAkC,qBAAqB,cAAc,cAAc,YAAY,kBAAkB,aAAa,kBAAkB,kBAAkB,aAAa,eAAe,iBAAiB,kBAAkB,sBAAsB,YAAY,gBAAgB,uBAAuB,eAAe,sBAAsB,aAAa,IAAI,WAAW,sCAAsC,0BAA0B,4BAA4B,UAAU,mBAAmB,mCAAmC,SAAS,aAAa,kCAAkC,kBAAkB,mBAAmB,oBAAoB,mBAAmB,gCAAgC,gBAAgB,iBAAiB,mBAAmB,SAAS,uBAAuB,gBAAgB,YAAY,wBAAwB,gBAAgB,eAAe,kBAAkB,cAAc,gBAAgB,wBAAwB,mBAAmB,WAAW,4BAA4B,4BAA4B,eAAe,8BAA8B,sCAAsC,mfAAmf,WAAW,UAAU,8BAA8B,yBAAyB,4BAA4B,cAAc,gBAAgB,aAAa,kBAAkB,mCAAmC,wGAAwG,eAAe,8CAA8C,qBAAqB,oCAAoC,qFAAqF,gBAAgB,8BAA8B,iBAAiB,8BAA8B,eAAe,8BAA8B,gCAAgC,cAAc,eAAe,8BAA8B,gCAAgC,cAAc,6CAA6C,gBAAgB,wBAAwB,mBAAmB,aAAa,8BAA8B,mBAAmB,8BAA8B,mBAAmB,WAAW,eAAe,mBAAmB,iBAAiB,kBAAkB,mBAAmB,qBAAqB,mBAAmB,gCAAgC,mBAAmB;AACxvK;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB,gCAA+B;;AAE/B;AACA;AACA,qCAAoC;AACpC,mCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;;AAEzB;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;;AAEA;AACA,gBAAe;;AAEf;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA,sBAAqB;AACrB,qBAAoB;AACpB,mBAAkB;;AAElB,gBAAe;;AAEf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA,gDAA+C;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap ffceba391a39c929c245","require('file-loader?name=[name].[ext]!../index.html');\r\nimport {silverTexture} from './textures'\r\n//import {quote} from './quote'\r\n// Credit:\r\n// http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/\r\n// http://paulbourke.net/geometry/polygonise/\r\n\r\nconst THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much\r\nconst OBJLoader = require('three-obj-loader');\r\nOBJLoader(THREE)\r\n\r\nimport Framework from './framework'\r\nimport LUT from './marching_cube_LUT.js'\r\nimport MarchingCubes from './marching_cubes.js'\r\n\r\nconst DEFAULT_VISUAL_DEBUG = false;\r\nconst DEFAULT_ISO_LEVEL = 1.0;\r\nconst DEFAULT_GRID_RES = 30;\r\nconst DEFAULT_GRID_WIDTH = 6;\r\nconst DEFAULT_GRID_HEIGHT = 17;\r\nconst DEFAULT_GRID_DEPTH = 6;\r\nconst DEFAULT_NUM_METABALLS = 7;\r\nconst DEFAULT_MIN_RADIUS = 0.5;\r\nconst DEFAULT_MAX_RADIUS = 1;\r\nconst DEFAULT_MAX_SPEEDX = 0.005;\r\nconst DEFAULT_MAX_SPEEDY = 0.3;\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'};\r\nvar loaded = false;\r\nvar red = new THREE.Color(1.0,0.0,0.0);\r\nvar green = new THREE.Color(0.0,1.0,0.0);\r\nvar glassGeo;\r\nvar lampGeo;\r\n\r\n// glass, emissive, iridescent\r\nvar g_mat = {\r\n uniforms: {\r\n u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/glass-vert.glsl'),\r\n fragmentShader: require('./shaders/glass-frag.glsl')\r\n};\r\n\r\n// metal\r\nvar m_mat = {\r\n uniforms: {\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/metal-vert.glsl'),\r\n fragmentShader: require('./shaders/metal-frag.glsl')\r\n};\r\n\r\n//const GLASS_MAT = new THREE.ShaderMaterial(g_mat);\r\nvar GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3});\r\nvar METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111});\r\n\r\nvar App = {\r\n //\r\n marchingCubes: undefined,\r\n config: {\r\n // Global control of all visual debugging.\r\n // This can be set to false to disallow any memory allocation of visual debugging components.\r\n // **Note**: If your application experiences performance drop, disable this flag.\r\n visualDebug: DEFAULT_VISUAL_DEBUG,\r\n\r\n // The isolevel for marching cubes\r\n isolevel: DEFAULT_ISO_LEVEL,\r\n\r\n // Grid resolution in each dimension. If gridRes = 4, then we have a 4x4x4 grid\r\n gridRes: DEFAULT_GRID_RES,\r\n\r\n // Total width of grid\r\n gridWidth: DEFAULT_GRID_WIDTH,\r\n\r\n gridHeight: DEFAULT_GRID_HEIGHT,\r\n\r\n gridDepth: DEFAULT_GRID_DEPTH,\r\n\r\n // Width of each voxel\r\n // Ideally, we want the voxel to be small (higher resolution)\r\n gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES,\r\n gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES,\r\n gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES,\r\n\r\n // Number of metaballs\r\n numMetaballs: DEFAULT_NUM_METABALLS,\r\n\r\n // Minimum radius of a metaball\r\n minRadius: DEFAULT_MIN_RADIUS,\r\n\r\n // Maxium radius of a metaball\r\n maxRadius: DEFAULT_MAX_RADIUS,\r\n\r\n // Maximum speed of a metaball\r\n maxSpeedX: DEFAULT_MAX_SPEEDX,\r\n maxSpeedY: DEFAULT_MAX_SPEEDY,\r\n maxSpeedZ: DEFAULT_MAX_SPEEDX, \r\n },\r\n\r\n // Scene's framework objects\r\n camera: undefined,\r\n scene: undefined,\r\n renderer: undefined,\r\n\r\n // Play/pause control for the simulation\r\n isPaused: false,\r\n color: 0xffffff\r\n};\r\n\r\n// called after the scene loads\r\nfunction onLoad(framework) {\r\n\r\n var {scene, camera, renderer, gui, stats} = framework;\r\n App.scene = scene;\r\n App.camera = camera;\r\n App.renderer = renderer;\r\n\r\n renderer.setClearColor( 0x111111 );\r\n //scene.add(new THREE.AxisHelper(20));\r\n\r\n var objLoader = new THREE.OBJLoader();\r\n var obj = objLoader.load(require('./assets/glass.obj'), function(obj) {\r\n glassGeo = obj.children[0].geometry;\r\n var glass = new THREE.Mesh(glassGeo, GLASS_MAT);\r\n glass.translateX(-1.5);\r\n glass.translateZ(-1.5);\r\n App.scene.add(glass);\r\n loaded = true;\r\n });\r\n\r\n var obj = objLoader.load(require('./assets/lamp.obj'), function(obj) {\r\n lampGeo = obj.children[0].geometry;\r\n var lamp = new THREE.Mesh(lampGeo, METAL_MAT);\r\n lamp.translateX(-1.5);\r\n lamp.translateZ(-1.5);\r\n App.scene.add(lamp);\r\n });\r\n\r\n setupCamera(App.camera);\r\n setupLights(App.scene);\r\n setupScene(App.scene);\r\n setupGUI(gui);\r\n}\r\n\r\nfunction cosine(a,b,c,d,t) {\r\n return a + b * Math.cos(2.0 * Math.PI * (c * t + d));\r\n}\r\n\r\n// called on frame updates\r\nfunction onUpdate(framework) {\r\n if (loaded) {\r\n var date = new Date();\r\n var sec = date.getSeconds();\r\n var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0);\r\n var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0);\r\n var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); \r\n GLASS_MAT.emissive.set(new THREE.Color(r,g,b));\r\n }\r\n if (App.marchingCubes) {\r\n App.marchingCubes.update();\r\n }\r\n}\r\n\r\nfunction setupCamera(camera) {\r\n // set camera position\r\n camera.position.set(25, 10, 25);\r\n camera.lookAt(new THREE.Vector3(8,0,-5));\r\n}\r\n\r\nfunction setupLights(scene) {\r\n\r\n // Directional light\r\n var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );\r\n directionalLight.color.setHSL(0.1, 1, 0.95);\r\n directionalLight.position.set(1, 10, 2);\r\n directionalLight.position.multiplyScalar(10);\r\n\r\n scene.add(directionalLight);\r\n}\r\n\r\nfunction setupScene(scene) {\r\n App.marchingCubes = new MarchingCubes(App);\r\n}\r\n\r\nfunction setupGUI(gui) {\r\n\r\n // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage\r\n\r\n gui.add(App.config, 'numMetaballs', 1, 10).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'minRadius', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxRadius', 1, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxSpeedY', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'isolevel', 0, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'gridRes', 1, 40).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n\r\n}\r\n\r\n// when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate\r\nFramework.init(onLoad, onUpdate);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n// this file is just for convenience. it sets up loading the mario obj and texture\r\n\r\nconst THREE = require('three');\r\n\r\nexport var silverTexture = new Promise((resolve, reject) => {\r\n (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) {\r\n resolve(texture);\r\n })\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/textures.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*(\\S*)\\s*\\(/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tObject.assign( EventDispatcher.prototype, {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\tvar REVISION = '82';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar BlendingMode = {\n\t\tNoBlending: NoBlending,\n\t\tNormalBlending: NormalBlending,\n\t\tAdditiveBlending: AdditiveBlending,\n\t\tSubtractiveBlending: SubtractiveBlending,\n\t\tMultiplyBlending: MultiplyBlending,\n\t\tCustomBlending: CustomBlending\n\t};\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar TextureMapping = {\n\t\tUVMapping: UVMapping,\n\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t};\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar TextureWrapping = {\n\t\tRepeatWrapping: RepeatWrapping,\n\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t};\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar TextureFilter = {\n\t\tNearestFilter: NearestFilter,\n\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\tLinearFilter: LinearFilter,\n\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t};\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\trandom16: function () {\n\n\t\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\t\treturn Math.random();\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: TextureIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.sourceFile = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\tvar count = 0;\n\tfunction TextureIdCount() { return count++; }\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\t\t\tthis.w = attribute.array[ index + 3 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyProjection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 projection matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\t\t\tvar d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide\n\n\t\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;\n\t\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;\n\t\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix4( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeFrustum: function ( left, right, bottom, top, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakePerspective: function ( fov, aspect, near, far ) {\n\n\t\t\tvar ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 );\n\t\t\tvar ymin = - ymax;\n\t\t\tvar xmin = ymin * aspect;\n\t\t\tvar xmax = ymax * aspect;\n\n\t\t\treturn this.makeFrustum( xmin, xmax, ymin, ymax, near, far );\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\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}\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\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}\\n\";\n\n\tvar 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\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n float maxComponent = max( max( value.r, value.g ), value.b );\\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n M = ceil( M * 255.0 ) / 255.0;\\n return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float D = max( maxRange / maxRGB, 1.0 );\\n D = min( floor( D ) / 255.0, 1.0 );\\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n vec4 vResult;\\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n vResult.w = fract(Le);\\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n return 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 float Le = value.z * 255.0 + value.w;\\n vec3 Xp_Y_XYZp;\\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\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\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color = pointLight.color;\\n\\t\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\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_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\\t#include \\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\\t#include \\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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar 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};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\\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_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar 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\";\n\n\tvar 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}\\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_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\";\n\n\tvar 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 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\\t\\t\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n return 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 return ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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 boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n return 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 color *= toneMappingExposure;\\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n color = max( vec3( 0.0 ), color - 0.004 );\\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar 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\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\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\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\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\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse = vec3( 0.0 );\\n\\treflectedLight.directSpecular = vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse = diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular = vec3( 0.0 );\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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 \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\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 \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\n}\\n\";\n\n\tvar normal_vert = \"varying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvNormal = normalize( normalMatrix * normal );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( (value && value.isColor) ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular : { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity : { value: 1 }, // temporary\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\n\t\t\t\t{\n\t\t\t\t\tscale : { value: 1 },\n\t\t\t\t\tdashSize : { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: {\n\n\t\t\t\topacity : { value: 1.0 }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\n\t\t\t\tlightPos: { value: new Vector3() }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\tShaderLib.standard.uniforms,\n\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t point.y < this.min.y || point.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyProjection( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( (fog && fog.isFog) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( (fog && fog.isFogExp2) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: MaterialIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( (currentValue && currentValue.isColor) ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( (currentValue && currentValue.isVector3) && (newValue && newValue.isVector3) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( (this.color && this.color.isColor) ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();\n\t\t\tif ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\n\t\t\tif ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.bumpMap && this.bumpMap.isTexture) ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( (this.normalMap && this.normalMap.isTexture) ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( (this.displacementMap && this.displacementMap.isTexture) ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.envMap && this.envMap.isTexture) ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\tvar count$1 = 0;\n\tfunction MaterialIdCount() { return count$1++; }\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tthis.makeEmpty();\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tvar array, offset, stride;\n\n\t\t\t\t\t\t\t\tif ( (attribute && attribute.isInterleavedBufferAttribute) ) {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.data.array;\n\t\t\t\t\t\t\t\t\toffset = attribute.offset;\n\t\t\t\t\t\t\t\t\tstride = attribute.data.stride;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.array;\n\t\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\t\tstride = 3;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor ( var i = offset, il = array.length; i < il; i += stride ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromArray( array, i );\n\t\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\t\t point.y < this.min.y || point.y > this.max.y ||\n\t\t\t\t\t point.z < this.min.z || point.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&\n\t\t\t\t ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\t\t box.max.z < this.min.z || box.min.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// 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.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box = new Box3();\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix3( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( (matrix && matrix.isMatrix4) ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.clearColor( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( (light && light.isPointLight) ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( (shadow && shadow.isSpotLightShadow) ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( (material && material.isMultiMaterial) ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: Object3DIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function(){}; \n\t\tthis.onAfterRender = function(){};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype, {\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( (object && object.isObject3D) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\tvar count$2 = 0;\n\tfunction Object3DIdCount() { return count$2++; }\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int16Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint16Array( array ), itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int32Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float64Array( array ), itemSize );\n\n\t}\n\n\t// Deprecated\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [ [] ];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype, {\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( (geometry && geometry.isGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( (mesh && mesh.isMesh) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\tvar dupIndex = - 1;\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tdupIndex = n;\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [ [] ];\n\t\t\tthis.colors = [];\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( var i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( var i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( var k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tvar count$3 = 0;\n\tfunction GeometryIdCount() { return count$3++; }\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'DirectGeometry';\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tcomputeBoundingBox: Geometry.prototype.computeBoundingBox,\n\t\tcomputeBoundingSphere: Geometry.prototype.computeBoundingSphere,\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tthis.index = index;\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( (attribute && attribute.isBufferAttribute) === false && (attribute && attribute.isInterleavedBufferAttribute) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToVector3Array( position.array );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToVector3Array( normal.array );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isPoints) || (object && object.isLine) ) {\n\n\t\t\t\tvar positions = new Float32Attribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32Attribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32Attribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( (object && object.isMesh) ) {\n\n\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isMesh) ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32Attribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32Attribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar positions = this.attributes.position.array;\n\n\t\t\tif ( positions !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromArray( positions );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar positions = this.attributes.position;\n\n\t\t\t\tif ( positions ) {\n\n\t\t\t\t\tvar array = positions.array;\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromArray( array );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i += 3 ) {\n\n\t\t\t\t\t\tvector.fromArray( array, i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC,\n\n\t\t\t\tpA = new Vector3(),\n\t\t\t\tpB = new Vector3(),\n\t\t\t\tpC = new Vector3(),\n\n\t\t\t\tcb = new Vector3(),\n\t\t\t\tab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( (geometry && geometry.isBufferGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {\n\n\t\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\t\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\t\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar uvs, intersection;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( attributes.uv !== undefined ) {\n\n\t\t\t\t\t\tuvs = attributes.uv.array;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = indices[ i ];\n\t\t\t\t\t\t\tb = indices[ i + 1 ];\n\t\t\t\t\t\t\tc = indices[ i + 2 ];\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length; i < l; i += 9 ) {\n\n\t\t\t\t\t\t\ta = i / 3;\n\t\t\t\t\t\t\tb = a + 1;\n\t\t\t\t\t\t\tc = a + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = (material && material.isMultiMaterial);\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );\n\t\tvar indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\t\tvar numberOfVertices = 0;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount( w, h, d ) {\n\n\t\t\tvar vertices = 0;\n\n\t\t\t// calculate the amount of vertices for each side (plane)\n\t\t\tvertices += (w + 1) * (h + 1) * 2; // xy\n\t\t\tvertices += (w + 1) * (d + 1) * 2; // xz\n\t\t\tvertices += (d + 1) * (h + 1) * 2; // zy\n\n\t\t\treturn vertices;\n\n\t\t}\n\n\t\tfunction calculateIndexCount( w, h, d ) {\n\n\t\t\tvar index = 0;\n\n\t\t\t// calculate the amount of squares for each side\n\t\t\tindex += w * h * 2; // xy\n\t\t\tindex += w * d * 2; // xz\n\t\t\tindex += d * h * 2; // zy\n\n\t\t\treturn index * 6; // two triangles per square => six vertices per square\n\n\t\t}\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth\t= width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\t\t\t\t\tvertices[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\t\t\t\t\tnormals[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tnormals[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tnormals[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// uvs\n\t\t\t\t\tuvs[ uvBufferOffset ] = ix / gridX;\n\t\t\t\t\tuvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\t\tuvBufferOffset += 2;\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\t// indices\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tindexBufferOffset += 6;\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar vertices = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar normals = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar uvs = new Float32Array( gridX1 * gridY1 * 2 );\n\n\t\tvar offset = 0;\n\t\tvar offset2 = 0;\n\n\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices[ offset ] = x;\n\t\t\t\tvertices[ offset + 1 ] = - y;\n\n\t\t\t\tnormals[ offset + 2 ] = 1;\n\n\t\t\t\tuvs[ offset2 ] = ix / gridX;\n\t\t\t\tuvs[ offset2 + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\toffset += 3;\n\t\t\t\toffset2 += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\toffset = 0;\n\n\t\tvar indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );\n\n\t\tfor ( var iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( var ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices[ offset ] = a;\n\t\t\t\tindices[ offset + 1 ] = b;\n\t\t\t\tindices[ offset + 2 ] = d;\n\n\t\t\t\tindices[ offset + 3 ] = b;\n\t\t\t\tindices[ offset + 4 ] = c;\n\t\t\t\tindices[ offset + 5 ] = d;\n\n\t\t\t\toffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makeFrustum(\n\t\t\t\t\tleft, left + width, top - height, top, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( (position && position.isInterleavedBufferAttribute) ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( 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\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( (map && map.isTexture) ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( (map && map.isWebGLRenderTarget) ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\t\t\tvar position = attributes.position;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar edges = {};\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;\n\t\t\tvar attribute = new BufferAttribute( new TypeArray( indices ), 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true;\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true;\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( (renderTarget && renderTarget.isWebGLRenderTargetCube) ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = (texture && texture.isCompressedTexture);\n\t\t\t\t\tvar isDataTexture = (texture.image[ 0 ] && texture.image[ 0 ].isDataTexture);\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( (texture && texture.isDepthTexture) ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( (texture && texture.isDataTexture) ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( (texture && texture.isCompressedTexture) ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( (renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture) ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a ) {\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tclearColor( 0, 0, 0, 1 );\n\t\t\tclearDepth( 1 );\n\t\t\tclearStencil( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tgl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction clearColor( r, g, b, a ) {\n\n\t\t\tcolorBuffer.setClear( r, g, b, a );\n\n\t\t}\n\n\t\tfunction clearDepth( depth ) {\n\n\t\t\tdepthBuffer.setClear( depth );\n\n\t\t}\n\n\t\tfunction clearStencil( stencil ) {\n\n\t\t\tstencilBuffer.setClear( stencil );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tclearColor: clearColor,\n\t\t\tclearDepth: clearDepth,\n\t\t\tclearStencil: clearStencil,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t// internal state cache\n\n\t\t_currentProgram = null,\n\t\t_currentRenderTarget = null,\n\t\t_currentFramebuffer = null,\n\t\t_currentMaterialId = - 1,\n\t\t_currentGeometryProgram = '',\n\t\t_currentCamera = null,\n\n\t\t_currentScissor = new Vector4(),\n\t\t_currentScissorTest = null,\n\n\t\t_currentViewport = new Vector4(),\n\n\t\t//\n\n\t\t_usedTextureUnits = 0,\n\n\t\t//\n\n\t\t_clearColor = new Color( 0x000000 ),\n\t\t_clearAlpha = 0,\n\n\t\t_width = _canvas.width,\n\t\t_height = _canvas.height,\n\n\t\t_pixelRatio = 1,\n\n\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t_scissorTest = false,\n\n\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t// frustum\n\n\t\t_frustum = new Frustum(),\n\n\t\t// clipping\n\n\t\t_clipping = new WebGLClipping(),\n\t\t_clippingEnabled = false,\n\t\t_localClippingEnabled = false,\n\n\t\t_sphere = new Sphere(),\n\n\t\t// camera matrices cache\n\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_vector3 = new Vector3(),\n\n\t\t// light arrays cache\n\n\t\t_lights = {\n\n\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\tshadows: []\n\n\t\t},\n\n\t\t// info\n\n\t\t_infoRender = {\n\n\t\t\tcalls: 0,\n\t\t\tvertices: 0,\n\t\t\tfaces: 0,\n\t\t\tpoints: 0\n\n\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\t\tvar backgroundCamera2 = new PerspectiveCamera();\n\t\tvar backgroundPlaneMesh = new Mesh(\n\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t);\n\t\tvar backgroundBoxShader = ShaderLib[ 'cube' ];\n\t\tvar backgroundBoxMesh = new Mesh(\n\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\tnew ShaderMaterial( {\n\t\t\t\tuniforms: backgroundBoxShader.uniforms,\n\t\t\t\tvertexShader: backgroundBoxShader.vertexShader,\n\t\t\t\tfragmentShader: backgroundBoxShader.fragmentShader,\n\t\t\t\tside: BackSide,\n\t\t\t\tdepthTest: false,\n\t\t\t\tdepthWrite: false,\n\t\t\t\tfog: false\n\t\t\t} )\n\t\t);\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction glClearColor( r, g, b, a ) {\n\n\t\t\tif ( _premultipliedAlpha === true ) {\n\n\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t}\n\n\t\t\tstate.clearColor( r, g, b, a );\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t ! material.isMeshStandardMaterial &&\n\t\t\t\t material.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar type = _gl.FLOAT;\n\t\t\t\t\t\tvar array = geometryAttribute.array;\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\n\t\t\t\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.FLOAT;\n\n\t\t\t\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.BYTE;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_BYTE;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\t\t\t\t\t\tvar buffer = objects.getAttributeBuffer( geometryAttribute );\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tglClearColor( background.r, background.g, background.b, 1 );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tbackgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t ! material.isRawShaderMaterial ||\n\t\t\t material.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes || \n\t \t\t\t\t materialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isShaderMaterial ||\n\t\t\t\t material.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\tm_uniforms.opacity.value = material.opacity;\n\n\t\t\t\t}\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\tr = 0, g = 0, b = 0,\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\tdistance,\n\t\t\tshadowMap,\n\n\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\t p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone( skin ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t\tthis.skin = skin;\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.skin = source.skin;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone( this );\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( (this.geometry && this.geometry.isGeometry) ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.type = type !== undefined ? type : UnsignedShortType;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar numEdges = 0;\n\n\t\t\t// allocate maximal size\n\t\t\tvar edges = new Uint32Array( 6 * faces.length );\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\tvar vertex = vertices[ edges [ 2 * i + j ] ];\n\n\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\tcoords[ index + 0 ] = vertex.x;\n\t\t\t\t\tcoords[ index + 1 ] = vertex.y;\n\t\t\t\t\tcoords[ index + 2 ] = vertex.z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// Indexed BufferGeometry\n\n\t\t\t\tvar indices = geometry.index.array;\n\t\t\t\tvar vertices = geometry.attributes.position;\n\t\t\t\tvar groups = geometry.groups;\n\t\t\t\tvar numEdges = 0;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.length );\n\n\t\t\t\t}\n\n\t\t\t\t// allocate maximal size\n\t\t\t\tvar edges = new Uint32Array( 2 * indices.length );\n\n\t\t\t\tfor ( var o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tvar group = groups[ o ];\n\n\t\t\t\t\tvar start = group.start;\n\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices[ i + j ];\n\t\t\t\t\t\t\tedge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];\n\t\t\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\t\tvar index2 = edges[ 2 * i + j ];\n\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices.getX( index2 );\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices.getY( index2 );\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices.getZ( index2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tvar vertices = geometry.attributes.position.array;\n\t\t\t\tvar numEdges = vertices.length / 3;\n\t\t\t\tvar numTris = numEdges / 3;\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numTris; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\tvar index = 18 * i + 6 * j;\n\n\t\t\t\t\t\tvar index1 = 9 * i + 3 * j;\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices[ index1 ];\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices[ index1 + 1 ];\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices[ index1 + 2 ];\n\n\t\t\t\t\t\tvar index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tcoords[ index + 3 ] = vertices[ index2 ];\n\t\t\t\t\t\tcoords[ index + 4 ] = vertices[ index2 + 1 ];\n\t\t\t\t\t\tcoords[ index + 5 ] = vertices[ index2 + 2 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// generate vertices and uvs\n\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j, p;\n\t\tvar u, v;\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tv = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tu = j / slices;\n\n\t\t\t\tp = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tvar indices = [];\n\t\tvar a, b, c, d;\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\ta = i * sliceCount + j;\n\t\t\t\tb = i * sliceCount + j + 1;\n\t\t\t\tc = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\td = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', Float32Attribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0 ; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols ; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius,detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t *\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar i, j, index = 0, indexOffset = 0;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\tuv.y = j / radialSegments;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\n\t\t// helper variables\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices[ vertexBufferOffset ] = vertex.x;\n\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vertex.y;\n\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vertex.z;\n\n\t\t\t\t// this vector is used to calculate the normal\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\n\t\t\t\t// normal\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals[ vertexBufferOffset ] = normal.x;\n\t\t\t\tnormals[ vertexBufferOffset + 1 ] = normal.y;\n\t\t\t\tnormals[ vertexBufferOffset + 2 ] = normal.z;\n\n\t\t\t\t// uv\n\t\t\t\tuvs[ uvBufferOffset ] = i / tubularSegments;\n\t\t\t\tuvs[ uvBufferOffset + 1 ] = j / radialSegments;\n\n\t\t\t\t// update offsets\n\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\tuvBufferOffset += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t// face two\n\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t// update offset\n\t\t\t\tindexBufferOffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// 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.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t},\n\n\t\t// Bezier Curves formulas obtained from\n\t\t// http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n\t\t// Quad Bezier Functions\n\n\t\tb2: ( function () {\n\n\t\t\tfunction b2p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p1( t, p ) {\n\n\t\t\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p2( t, p ) {\n\n\t\t\t\treturn t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b2( t, p0, p1, p2 ) {\n\n\t\t\t\treturn b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\t// Cubic Bezier Functions\n\n\t\tb3: ( function () {\n\n\t\t\tfunction b3p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p1( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * k * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p2( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * t * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p3( t, p ) {\n\n\t\t\t\treturn t * t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b3( t, p0, p1, p2, p3 ) {\n\n\t\t\t\treturn b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( (font && font.isFont) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * based on THREE.SphereGeometry\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );\n\n\t\tvar positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\tvar index = 0, vertices = [], normal = new Vector3();\n\n\t\tfor ( var y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = y / heightSegments;\n\n\t\t\tfor ( var x = 0; x <= widthSegments; x ++ ) {\n\n\t\t\t\tvar u = x / widthSegments;\n\n\t\t\t\tvar px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvar py = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvar pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tnormal.set( px, py, pz ).normalize();\n\n\t\t\t\tpositions.setXYZ( index, px, py, pz );\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\tverticesRow.push( index );\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tvertices.push( verticesRow );\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var y = 0; y < heightSegments; y ++ ) {\n\n\t\t\tfor ( var x = 0; x < widthSegments; x ++ ) {\n\n\t\t\t\tvar v1 = vertices[ y ][ x + 1 ];\n\t\t\t\tvar v2 = vertices[ y ][ x ];\n\t\t\t\tvar v3 = vertices[ y + 1 ][ x ];\n\t\t\t\tvar v4 = vertices[ y + 1 ][ x + 1 ];\n\n\t\t\t\tif ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );\n\t\t\t\tif ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', positions );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 );\n\t\tvar indexCount = thetaSegments * phiSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// some helper variables\n\t\tvar index = 0, indexOffset = 0, segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\t// values are generate from the inside of the ring to the outside\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, 0, 1 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex++;\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\t // points - to create a closed torus, one must use a set of points\n\t // like so: [ a, b, c, d, a ], see first is the same as last.\n\t // segments - the number of circumference segments to create\n\t // phiStart - the starting radian\n\t // phiLength - the radian (0 to 2PI) range of the lathed section\n\t // 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( segments + 1 ) * points.length;\n\t\tvar indexCount = segments * points.length * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar index = 0, indexOffset = 0, base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t} // next row\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t *\n\t * Creates a one-sided polygonal geometry from a path shape. Similar to\n\t * ExtrudeGeometry.\n\t *\n\t * parameters = {\n\t *\n\t *\tcurveSegments: , // number of points on the curves. NOT USED AT THE MOMENT.\n\t *\n\t *\tmaterial: // material index for front and back faces\n\t *\tuvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ShapeGeometry( shapes, options ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( Array.isArray( shapes ) === false ) shapes = [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * Add an array of shapes to THREE.ShapeGeometry.\n\t */\n\tShapeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tfor ( var i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tthis.addShape( shapes[ i ], options );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.\n\t */\n\tShapeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tif ( options === undefined ) options = {};\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar material = options.material;\n\t\tvar uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;\n\n\t\t//\n\n\t\tvar i, l, hole;\n\n\t\tvar shapesOffset = this.vertices.length;\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe...\n\n\t\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\t\thole = holes[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( hole ) ) {\n\n\t\t\t\t\tholes[ i ] = hole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false;\n\n\t\t}\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t// Vertices\n\n\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\thole = holes[ i ];\n\t\t\tvertices = vertices.concat( hole );\n\n\t\t}\n\n\t\t//\n\n\t\tvar vert, vlen = vertices.length;\n\t\tvar face, flen = faces.length;\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = vertices[ i ];\n\n\t\t\tthis.vertices.push( new Vector3( vert.x, vert.y, 0 ) );\n\n\t\t}\n\n\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\tface = faces[ i ];\n\n\t\t\tvar a = face[ 0 ] + shapesOffset;\n\t\t\tvar b = face[ 1 ] + shapesOffset;\n\t\t\tvar c = face[ 2 ] + shapesOffset;\n\n\t\t\tthis.faces.push( new Face3( a, b, c, null, null, material ) );\n\t\t\tthis.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tvar geometry2;\n\n\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar vertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tvar key = edge.toString();\n\n\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\thash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\thash[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar coords = [];\n\n\t\tfor ( var key in hash ) {\n\n\t\t\tvar h = hash[ key ];\n\n\t\t\tif ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = vertices[ h.vert1 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t\tvertex = vertices[ h.vert2 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) );\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// used to calculate buffer length\n\n\t\tvar nbCap = 0;\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) nbCap ++;\n\t\t\tif ( radiusBottom > 0 ) nbCap ++;\n\n\t\t}\n\n\t\tvar vertexCount = calculateVertexCount();\n\t\tvar indexCount = calculateIndexCount();\n\n\t\t// buffers\n\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\n\t\tvar index = 0,\n\t\t indexOffset = 0,\n\t\t indexArray = [],\n\t\t halfHeight = height / 2;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount() {\n\n\t\t\tvar count = ( radialSegments + 1 ) * ( heightSegments + 1 );\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap );\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction calculateIndexCount() {\n\n\t\t\tvar count = radialSegments * heightSegments * 2 * 3;\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += radialSegments * nbCap * 3;\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\t\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\t\t\t\t\tindexRow.push( index );\n\n\t\t\t\t\t// increase index\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\tvar i1 = indexArray[ y ][ x ];\n\t\t\t\t\tvar i2 = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar i3 = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar i4 = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices.setX( indexOffset, i1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i3 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// update counters\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = 0.5;\n\t\t\t\tuv.y = 0.5;\n\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t}\n\n\t\t\t\t// update counters\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tvar vertices = segments + 2;\n\n\t\tvar positions = new Float32Array( vertices * 3 );\n\t\tvar normals = new Float32Array( vertices * 3 );\n\t\tvar uvs = new Float32Array( vertices * 2 );\n\n\t\t// center data is already zero, but need to set a few extras\n\t\tnormals[ 2 ] = 1.0;\n\t\tuvs[ 0 ] = 0.5;\n\t\tuvs[ 1 ] = 0.5;\n\n\t\tfor ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\tpositions[ i ] = radius * Math.cos( segment );\n\t\t\tpositions[ i + 1 ] = radius * Math.sin( segment );\n\n\t\t\tnormals[ i + 2 ] = 1; // normal z\n\n\t\t\tuvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;\n\t\t\tuvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry,\n\t\tBoxGeometry: BoxGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib[ \"lights\" ],\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = materials instanceof Array ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction XHRLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( XHRLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[1];\n\t\t\t\tvar isBase64 = !!dataUriRegexResult[2];\n\t\t\t\tvar data = dataUriRegexResult[3];\n\n\t\t\t\tdata = window.decodeURIComponent(data);\n\n\t\t\t\tif( isBase64 ) {\n\t\t\t\t\tdata = window.atob(data);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { \"type\" : mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tvar DataTextureLoader = BinaryTextureLoader;\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( BinaryTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\t\t\timage.onload = function () {\n\n\t\t\t\timage.onload = null;\n\n\t\t\t\tURL.revokeObjectURL( image.src );\n\n\t\t\t\tif ( onLoad ) onLoad( image );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t};\n\t\t\timage.onerror = onError;\n\n\t\t\tif ( url.indexOf( 'data:' ) === 0 ) {\n\n\t\t\t\timage.src = url;\n\n\t\t\t} else {\n\n\t\t\t\tvar loader = new XHRLoader();\n\t\t\t\tloader.setPath( this.path );\n\t\t\t\tloader.setResponseType( 'blob' );\n\t\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\t\tloader.load( url, function ( blob ) {\n\n\t\t\t\t\timage.src = URL.createObjectURL( blob );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( light ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true,\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function() {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function() {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function( timeOffset ) {\n\n\t\t\tif( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function( timeScale ) {\n\n\t\t\tif( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== -1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to , 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function() {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function() {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number',\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max(\n\t\t\t\t\t\tduration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0;\n\t\t\t\t\t\t\t\tm !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack(\n\t\t\t\t\t\t\t\t'.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader ( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tscope.parse( JSON.parse( text ), onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.SplineCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = 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\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\t// TODO: Transformation for Curves?\n\n\t/**************************************************************\n\t *\t3D Curves\n\t **************************************************************/\n\n\t// A Factory method for creating new curve subclasses\n\n\tCurve.create = function ( constructor, getPointFunc ) {\n\n\t\tconstructor.prototype = Object.create( Curve.prototype );\n\t\tconstructor.prototype.constructor = constructor;\n\t\tconstructor.prototype.getPoint = getPointFunc;\n\n\t\treturn constructor;\n\n\t};\n\n\t/**************************************************************\n\t *\tLine\n\t **************************************************************/\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**************************************************************\n\t *\tEllipse curve\n\t **************************************************************/\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar CurveUtils = {\n\n\t\ttangentQuadraticBezier: function ( t, p0, p1, p2 ) {\n\n\t\t\treturn 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );\n\n\t\t},\n\n\t\t// Puay Bing, thanks for helping with this derivative!\n\n\t\ttangentCubicBezier: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\treturn - 3 * p0 * ( 1 - t ) * ( 1 - t ) +\n\t\t\t\t3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +\n\t\t\t\t6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +\n\t\t\t\t3 * t * t * p3;\n\n\t\t},\n\n\t\ttangentSpline: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\t// To check if my formulas are correct\n\n\t\t\tvar h00 = 6 * t * t - 6 * t; \t// derived from 2t^3 − 3t^2 + 1\n\t\t\tvar h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t\n\t\t\tvar h01 = - 6 * t * t + 6 * t; \t// − 2t3 + 3t2\n\t\t\tvar h11 = 3 * t * t - 2 * t;\t// t3 − t2\n\n\t\t\treturn h00 + h10 + h01 + h11;\n\n\t\t},\n\n\t\t// Catmull-Rom\n\n\t\tinterpolate: function( p0, p1, p2, p3, t ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t * t2;\n\t\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t};\n\n\t/**************************************************************\n\t *\tSpline curve\n\t **************************************************************/\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\treturn new Vector2(\n\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight )\n\t\t);\n\n\t};\n\n\t/**************************************************************\n\t *\tCubic Bezier curve\n\t **************************************************************/\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b3 = ShapeUtils.b3;\n\n\t\treturn new Vector2(\n\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t);\n\n\t};\n\n\tCubicBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentCubicBezier = CurveUtils.tangentCubicBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\ttangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t).normalize();\n\n\t};\n\n\t/**************************************************************\n\t *\tQuadratic Bezier curve\n\t **************************************************************/\n\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b2 = ShapeUtils.b2;\n\n\t\treturn new Vector2(\n\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t);\n\n\t};\n\n\n\tQuadraticBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\ttangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t).normalize();\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t *\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\n\t// minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\tfunction ShapePath() {\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\t}\n\n\tShapePath.prototype = {\n\t\tmoveTo: function ( x, y ) {\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push(this.currentPath);\n\t\t\tthis.currentPath.moveTo( x, y );\n\t\t},\n\t\tlineTo: function ( x, y ) {\n\t\t\tthis.currentPath.lineTo( x, y );\n\t\t},\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\t\t},\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\t\t},\n\t\tsplineThru: function ( pts ) {\n\t\t\tthis.currentPath.splineThru( pts );\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar offset = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar ret = createPath( chars[ i ], scale, offset );\n\t\t\t\t\toffset += ret.offset;\n\n\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offset ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3;\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb2( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tb2( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb3( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tb3( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offset: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tfunction getAudioContext() {\n\n\t\tif ( context === undefined ) {\n\n\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn context;\n\n\t}\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = getAudioContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = getAudioContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\t\tthis.source = this.context.createBufferSource();\n\t\tthis.source.onended = this.onEnded.bind( this );\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.source.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.source.buffer;\n\t\t\tsource.loop = this.source.loop;\n\t\t\tsource.onended = this.source.onended;\n\t\t\tsource.start( 0, this.startTime );\n\t\t\tsource.playbackRate.value = this.playbackRate;\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.value = this.playbackRate;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.source.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.loop = value;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\t\t\tmixFunction = this._slerp;\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\n\t\t\t\tbufferType = Array,\t\tmixFunction = this._select;\t\tbreak;\n\n\t\t\tdefault:\t\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( (root && root.isAnimationObjectGroup) ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:\\w+[\\/:])*)(\\w+)?(?:\\.(\\w+)(?:\\[(.+)\\])?)?\\.(\\w+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tvar knownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis.loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype, {\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function() {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function() {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function() {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function() {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Spline from Tween.js, slightly optimized (and trashed)\n\t * http://sole.github.com/tween.js/examples/05_spline.html\n\t *\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Spline( points ) {\n\n\t\tthis.points = points;\n\n\t\tvar c = [], v3 = { x: 0, y: 0, z: 0 },\n\t\tpoint, intPoint, weight, w2, w3,\n\t\tpa, pb, pc, pd;\n\n\t\tthis.initFromArray = function ( a ) {\n\n\t\t\tthis.points = [];\n\n\t\t\tfor ( var i = 0; i < a.length; i ++ ) {\n\n\t\t\t\tthis.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getPoint = function ( k ) {\n\n\t\t\tpoint = ( this.points.length - 1 ) * k;\n\t\t\tintPoint = Math.floor( point );\n\t\t\tweight = point - intPoint;\n\n\t\t\tc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;\n\t\t\tc[ 1 ] = intPoint;\n\t\t\tc[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;\n\t\t\tc[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;\n\n\t\t\tpa = this.points[ c[ 0 ] ];\n\t\t\tpb = this.points[ c[ 1 ] ];\n\t\t\tpc = this.points[ c[ 2 ] ];\n\t\t\tpd = this.points[ c[ 3 ] ];\n\n\t\t\tw2 = weight * weight;\n\t\t\tw3 = weight * w2;\n\n\t\t\tv3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );\n\t\t\tv3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );\n\t\t\tv3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );\n\n\t\t\treturn v3;\n\n\t\t};\n\n\t\tthis.getControlPointsArray = function () {\n\n\t\t\tvar i, p, l = this.points.length,\n\t\t\t\tcoords = [];\n\n\t\t\tfor ( i = 0; i < l; i ++ ) {\n\n\t\t\t\tp = this.points[ i ];\n\t\t\t\tcoords[ i ] = [ p.x, p.y, p.z ];\n\n\t\t\t}\n\n\t\t\treturn coords;\n\n\t\t};\n\n\t\t// approximate length by summing linear segments\n\n\t\tthis.getLength = function ( nSubDivisions ) {\n\n\t\t\tvar i, index, nSamples, position,\n\t\t\t\tpoint = 0, intPoint = 0, oldIntPoint = 0,\n\t\t\t\toldPosition = new Vector3(),\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tchunkLengths = [],\n\t\t\t\ttotalLength = 0;\n\n\t\t\t// first point has 0 length\n\n\t\t\tchunkLengths[ 0 ] = 0;\n\n\t\t\tif ( ! nSubDivisions ) nSubDivisions = 100;\n\n\t\t\tnSamples = this.points.length * nSubDivisions;\n\n\t\t\toldPosition.copy( this.points[ 0 ] );\n\n\t\t\tfor ( i = 1; i < nSamples; i ++ ) {\n\n\t\t\t\tindex = i / nSamples;\n\n\t\t\t\tposition = this.getPoint( index );\n\t\t\t\ttmpVec.copy( position );\n\n\t\t\t\ttotalLength += tmpVec.distanceTo( oldPosition );\n\n\t\t\t\toldPosition.copy( position );\n\n\t\t\t\tpoint = ( this.points.length - 1 ) * index;\n\t\t\t\tintPoint = Math.floor( point );\n\n\t\t\t\tif ( intPoint !== oldIntPoint ) {\n\n\t\t\t\t\tchunkLengths[ intPoint ] = totalLength;\n\t\t\t\t\toldIntPoint = intPoint;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// last point ends with total length\n\n\t\t\tchunkLengths[ chunkLengths.length ] = totalLength;\n\n\t\t\treturn { chunks: chunkLengths, total: totalLength };\n\n\t\t};\n\n\t\tthis.reparametrizeByArcLength = function ( samplingCoef ) {\n\n\t\t\tvar i, j,\n\t\t\t\tindex, indexCurrent, indexNext,\n\t\t\t\trealDistance,\n\t\t\t\tsampling, position,\n\t\t\t\tnewpoints = [],\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tsl = this.getLength();\n\n\t\t\tnewpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );\n\n\t\t\tfor ( i = 1; i < this.points.length; i ++ ) {\n\n\t\t\t\t//tmpVec.copy( this.points[ i - 1 ] );\n\t\t\t\t//linearDistance = tmpVec.distanceTo( this.points[ i ] );\n\n\t\t\t\trealDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];\n\n\t\t\t\tsampling = Math.ceil( samplingCoef * realDistance / sl.total );\n\n\t\t\t\tindexCurrent = ( i - 1 ) / ( this.points.length - 1 );\n\t\t\t\tindexNext = i / ( this.points.length - 1 );\n\n\t\t\t\tfor ( j = 1; j < sampling - 1; j ++ ) {\n\n\t\t\t\t\tindex = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );\n\n\t\t\t\t\tposition = this.getPoint( index );\n\t\t\t\t\tnewpoints.push( tmpVec.copy( position ).clone() );\n\n\t\t\t\t}\n\n\t\t\t\tnewpoints.push( tmpVec.copy( this.points[ i ] ).clone() );\n\n\t\t\t}\n\n\t\t\tthis.points = newpoints;\n\n\t\t};\n\n\t\t// Catmull-Rom\n\n\t\tfunction interpolate( p0, p1, p2, p3, t, t2, t3 ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5,\n\t\t\t\tv1 = ( p3 - p1 ) * 0.5;\n\n\t\t\treturn ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new Geometry();\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.colors.push( new Color( 0, 0, 1 ) );\n\t\t\t\tgeometry.colors.push( new Color( 0, 1, 0 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.dynamic = true;\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( (object && object.isBone) ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar geometry = this.geometry;\n\n\t\tvar matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld );\n\n\t\tvar boneMatrix = new Matrix4();\n\n\t\tvar j = 0;\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\tgeometry.vertices[ j ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\tgeometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.verticesNeedUpdate = true;\n\n\t\tgeometry.computeBoundingSphere();\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction HemisphereLightHelper( light, sphereSize ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.colors = [ new Color(), new Color() ];\n\n\t\tvar geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tgeometry.rotateX( - Math.PI / 2 );\n\n\t\tfor ( var i = 0, il = 8; i < il; i ++ ) {\n\n\t\t\tgeometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];\n\n\t\t}\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } );\n\n\t\tthis.lightSphere = new Mesh( geometry, material );\n\t\tthis.add( this.lightSphere );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.lightSphere.geometry.dispose();\n\t\tthis.lightSphere.material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tthis.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tthis.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tthis.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\t\t\tthis.lightSphere.geometry.colorsNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tdivisions = divisions || 1;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = ( size * 2 ) / divisions;\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - size, 0, k, size, 0, k );\n\t\t\tvertices.push( k, 0, - size, k, 0, size );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new Geometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar hexFrustum = 0xffaa00;\n\t\tvar hexCone = 0xff0000;\n\t\tvar hexUp = 0x00aaff;\n\t\tvar hexTarget = 0xffffff;\n\t\tvar hexCross = 0x333333;\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", hexFrustum );\n\t\taddLine( \"n2\", \"n4\", hexFrustum );\n\t\taddLine( \"n4\", \"n3\", hexFrustum );\n\t\taddLine( \"n3\", \"n1\", hexFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", hexFrustum );\n\t\taddLine( \"f2\", \"f4\", hexFrustum );\n\t\taddLine( \"f4\", \"f3\", hexFrustum );\n\t\taddLine( \"f3\", \"f1\", hexFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", hexFrustum );\n\t\taddLine( \"n2\", \"f2\", hexFrustum );\n\t\taddLine( \"n3\", \"f3\", hexFrustum );\n\t\taddLine( \"n4\", \"f4\", hexFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", hexCone );\n\t\taddLine( \"p\", \"n2\", hexCone );\n\t\taddLine( \"p\", \"n3\", hexCone );\n\t\taddLine( \"p\", \"n4\", hexCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", hexUp );\n\t\taddLine( \"u2\", \"u3\", hexUp );\n\t\taddLine( \"u3\", \"u1\", hexUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", hexTarget );\n\t\taddLine( \"p\", \"c\", hexCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", hexCross );\n\t\taddLine( \"cn3\", \"cn4\", hexCross );\n\n\t\taddLine( \"cf1\", \"cf2\", hexCross );\n\t\taddLine( \"cf3\", \"cf4\", hexCross );\n\n\t\tfunction addLine( a, b, hex ) {\n\n\t\t\taddPoint( a, hex );\n\t\t\taddPoint( b, hex );\n\n\t\t}\n\n\t\tfunction addPoint( id, hex ) {\n\n\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\tgeometry.colors.push( new Color( hex ) );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( geometry.vertices.length - 1 );\n\n\t\t}\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tgeometry.vertices[ points[ i ] ].copy( vector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.verticesNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\t// a helper to show the world-axis-aligned bounding box for an object\n\n\tfunction BoundingBoxHelper( object, hex ) {\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0x888888;\n\n\t\tthis.object = object;\n\n\t\tthis.box = new Box3();\n\n\t\tMesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) );\n\n\t}\n\n\tBoundingBoxHelper.prototype = Object.create( Mesh.prototype );\n\tBoundingBoxHelper.prototype.constructor = BoundingBoxHelper;\n\n\tBoundingBoxHelper.prototype.update = function () {\n\n\t\tthis.box.setFromObject( this.object );\n\n\t\tthis.box.getSize( this.scale );\n\n\t\tthis.box.getCenter( this.position );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar 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 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( (object && object.isBox3) ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry = new BufferGeometry();\n\tlineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\tvar coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = new Float32Array( [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t] );\n\n\t\tvar colors = new Float32Array( [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t] );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\tvar CatmullRomCurve3 = ( function() {\n\n\t\tvar\n\t\t\ttmp = new Vector3(),\n\t\t\tpx = new CubicPoly(),\n\t\t\tpy = new CubicPoly(),\n\t\t\tpz = new CubicPoly();\n\n\t\t/*\n\t\tBased on an optimized c++ solution in\n\t\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t\t - http://ideone.com/NoEbVM\n\n\t\tThis CubicPoly class could be used for reusing some variables and calculations,\n\t\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\t\twhich can be placed in CurveUtils.\n\t\t*/\n\n\t\tfunction CubicPoly() {}\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tCubicPoly.prototype.init = function( x0, x1, t0, t1 ) {\n\n\t\t\tthis.c0 = x0;\n\t\t\tthis.c1 = t0;\n\t\t\tthis.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tthis.c3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t};\n\n\t\tCubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\t// initCubicPoly\n\t\t\tthis.init( x1, x2, t1, t2 );\n\n\t\t};\n\n\t\t// standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4\n\t\tCubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {\n\n\t\t\tthis.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t};\n\n\t\tCubicPoly.prototype.calc = function( t ) {\n\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t2 * t;\n\t\t\treturn this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;\n\n\t\t};\n\n\t\t// Subclass Three.js curve\n\t\treturn Curve.create(\n\n\t\t\tfunction ( p /* array of Vector3 */ ) {\n\n\t\t\t\tthis.points = p || [];\n\t\t\t\tthis.closed = false;\n\n\t\t\t},\n\n\t\t\tfunction ( t ) {\n\n\t\t\t\tvar points = this.points,\n\t\t\t\t\tpoint, intPoint, weight, l;\n\n\t\t\t\tl = points.length;\n\n\t\t\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\t\t\tpoint = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\t\t\tintPoint = Math.floor( point );\n\t\t\t\tweight = point - intPoint;\n\n\t\t\t\tif ( this.closed ) {\n\n\t\t\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\t\t\tintPoint = l - 2;\n\t\t\t\t\tweight = 1;\n\n\t\t\t\t}\n\n\t\t\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\t\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate first point\n\t\t\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\t\t\tp0 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tp1 = points[ intPoint % l ];\n\t\t\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\t\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate last point\n\t\t\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\t\t\tp3 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t\t\t// safety check for repeated points\n\t\t\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t\t\t}\n\n\t\t\t\tvar v = new Vector3(\n\t\t\t\t\tpx.calc( weight ),\n\t\t\t\t\tpy.calc( weight ),\n\t\t\t\t\tpz.calc( weight )\n\t\t\t\t);\n\n\t\t\t\treturn v;\n\n\t\t\t}\n\n\t\t);\n\n\t} )();\n\n\t/**************************************************************\n\t *\tClosed Spline 3D curve\n\t **************************************************************/\n\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t/**************************************************************\n\t *\tSpline 3D curve\n\t **************************************************************/\n\n\n\tvar SplineCurve3 = Curve.create(\n\n\t\tfunction ( points /* array of Vector3 */ ) {\n\n\t\t\tconsole.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );\n\t\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar points = this.points;\n\t\t\tvar point = ( points.length - 1 ) * t;\n\n\t\t\tvar intPoint = Math.floor( point );\n\t\t\tvar weight = point - intPoint;\n\n\t\t\tvar point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];\n\t\t\tvar point1 = points[ intPoint ];\n\t\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\t\treturn new Vector3(\n\t\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight ),\n\t\t\t\tinterpolate( point0.z, point1.z, point2.z, point3.z, weight )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tCubic Bezier 3D curve\n\t **************************************************************/\n\n\tvar CubicBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2, v3 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\t\t\tthis.v3 = v3;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b3 = ShapeUtils.b3;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),\n\t\t\t\tb3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tQuadratic Bezier 3D curve\n\t **************************************************************/\n\n\tvar QuadraticBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b2 = ShapeUtils.b2;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y ),\n\t\t\t\tb2( t, this.v0.z, this.v1.z, this.v2.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tLine3D\n\t **************************************************************/\n\n\tvar LineCurve3 = Curve.create(\n\n\t\tfunction ( v1, v2 ) {\n\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tif ( t === 1 ) {\n\n\t\t\t\treturn this.v2.clone();\n\n\t\t\t}\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\t\tvector.multiplyScalar( t );\n\t\t\tvector.add( this.v1 );\n\n\t\t\treturn vector;\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tArc curve\n\t **************************************************************/\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4 ( a, b, c, d, normal, color, materialIndex ) {\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction PointCloud ( geometry, material ) {\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction ParticleSystem ( geometry, material ) {\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction PointCloudMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleBasicMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleSystemMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction Vertex ( x, y, z ) {\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\t}\n\n\t//\n\n\tfunction EdgesHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\tfunction WireframeHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Line3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix3.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\t\textractPosition: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\t\t},\n\t\tsetRotationFromQuaternion: function ( q ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );\n\t\t\treturn vector.applyProjection( this );\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t},\n\t\trotateAxis: function ( v ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\ttranslate: function ( v ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\t\t},\n\t\trotateX: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\t\t},\n\t\trotateY: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\t\t},\n\t\trotateZ: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\t\t},\n\t\trotateByAxis: function ( axis, angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.assign( Plane.prototype, {\n\t\tisIntersectionLine: function ( line ) {\n\t\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\t\treturn this.intersectsLine( line );\n\t\t}\n\t} );\n\n\tObject.assign( Quaternion.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\t\treturn vector.applyQuaternion( this );\n\t\t}\n\t} );\n\n\tObject.assign( Ray.prototype, {\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t}\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\t\textrude: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\t\t}\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\t\tsetEulerFromRotationMatrix: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Object3D.prototype, {\n\t\tgetChildByName: function ( name ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\t\t},\n\t\trenderDepth: function ( value ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\t\t}\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\t\teulerOrder: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\t\tobjects: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\t\tlength: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );\n\t\t\t\treturn this.array.length;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\t\taddIndex: function ( index ) {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\t\t\tif ( indexOffset !== undefined ) {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\t\t},\n\t\tclearDrawCalls: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\t\t},\n\t\tcomputeTangents: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\t\t},\n\t\tcomputeOffsets: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\t\twrapAround: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\t\tmetal: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\t\tderivatives: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tEventDispatcher.prototype = Object.assign( Object.create( {\n\n\t\t// Note: Extra base ensures these properties are not 'assign'ed.\n\n\t\tconstructor: EventDispatcher,\n\n\t\tapply: function ( target ) {\n\n\t\t\tconsole.warn( \"THREE.EventDispatcher: .apply is deprecated, \" +\n\t\t\t\t\t\"just inherit or Object.assign the prototype to mix-in.\" );\n\n\t\t\tObject.assign( target, this );\n\n\t\t}\n\n\t} ), EventDispatcher.prototype );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\t\tdynamic: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\t\tsupportsFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\t\t\treturn this.capabilities.vertexTextures;\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\t\t},\n\t\tinitMaterial: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\t\t},\n\t\taddPrePlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\t\t},\n\t\taddPostPlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\t\t},\n\t\tupdateShadowMap: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.enabled;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.cullFace;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\t\tcullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\t\twrapS: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Audio.prototype, {\n\t\tload: function ( file ) {\n\t\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' );\n\t\t\tvar scope = this;\n\t\t\tvar audioLoader = new AudioLoader();\n\t\t\taudioLoader.load( file, function ( buffer ) {\n\t\t\t\tscope.setBuffer( buffer );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\t} );\n\n\tObject.assign( AudioAnalyser.prototype, {\n\t\tgetData: function ( file ) {\n\t\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\t\treturn this.getFrequencyData();\n\t\t}\n\t} );\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector () {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function ( vector, camera ) {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer () {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.TextureIdCount = TextureIdCount;\n\texports.Texture = Texture;\n\texports.MaterialIdCount = MaterialIdCount;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.XHRLoader = XHRLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.getAudioContext = getAudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3DIdCount = Object3DIdCount;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Spline = Spline;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.ColorKeywords = ColorKeywords;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.ShapePath = ShapePath;\n\texports.Path = Path;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.CurveUtils = CurveUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.BlendingMode = BlendingMode;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.TextureMapping = TextureMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.TextureWrapping = TextureWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.TextureFilter = TextureFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MultiMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Sprite;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n\tObject.defineProperty( exports, 'AudioContext', {\n\t\tget: function () {\n\t\t\treturn exports.getAudioContext();\n\t\t}\n\t});\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 2\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/silver-3da470.bmp\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/silver.bmp\n// module id = 3\n// module chunks = 0","\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\nimport Stats from 'stats-js'\r\nimport DAT from 'dat-gui'\r\n\r\n// when the scene is done initializing, the function passed as `callback` will be executed\r\n// then, every frame, the function passed as `update` will be executed\r\nfunction init(callback, update) {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var framework = {\r\n gui: gui,\r\n stats: stats\r\n };\r\n\r\n // run this function after the window loads\r\n window.addEventListener('load', function() {\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x020202, 0);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.target.set(0, 0, 0);\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n controls.addEventListener('change', function() {\r\n camera.hasMoved = true;\r\n });\r\n\r\n document.body.appendChild(renderer.domElement);\r\n\r\n // resize the canvas when the window changes\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n }, false);\r\n\r\n // assign THREE.js objects to the object we will return\r\n framework.scene = scene;\r\n framework.camera = camera;\r\n framework.renderer = renderer;\r\n\r\n // begin the animation loop\r\n (function tick() {\r\n stats.begin();\r\n update(framework); // perform any requested updates\r\n renderer.render(scene, camera); // render the scene\r\n stats.end();\r\n requestAnimationFrame(tick); // register to call this again when the browser renders a new frame\r\n })();\r\n\r\n // we will pass the scene, gui, renderer, camera, etc... to the callback function\r\n return callback(framework);\r\n });\r\n}\r\n\r\nexport default {\r\n init: init\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/framework.js","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 5\n// module chunks = 0","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 6\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n height: 1em;\\n border-radius: 1em;\\n background-color: #eee;\\n padding: 0 0.5em;\\n overflow: hidden;\\n}\\n\\n.slider-fg {\\n padding: 1px 0 2px 0;\\n background-color: #aaa;\\n height: 1em;\\n margin-left: -0.5em;\\n padding-right: 0.5em;\\n border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n display: inline-block;\\n border-radius: 1em;\\n background-color: #fff;\\n border: 1px solid #aaa;\\n content: '';\\n float: right;\\n margin-right: -1em;\\n margin-top: -1px;\\n height: 0.9em;\\n width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 7\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 8\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 9\n// module chunks = 0","/////////////////////////////////////\r\n// Marching cubes lookup tables\r\n/////////////////////////////////////\r\n\r\n// Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/\r\n// These tables are straight from Paul Bourke's page:\r\n// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/\r\n// who in turn got them from Cory Gene Bloyd.\r\n\r\nvar EDGE_TABLE = new Int32Array([\r\n 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,\r\n 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,\r\n 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,\r\n 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,\r\n 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,\r\n 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,\r\n 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,\r\n 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,\r\n 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c,\r\n 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,\r\n 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc,\r\n 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,\r\n 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c,\r\n 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,\r\n 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,\r\n 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,\r\n 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,\r\n 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,\r\n 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,\r\n 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,\r\n 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,\r\n 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,\r\n 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,\r\n 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460,\r\n 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,\r\n 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0,\r\n 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,\r\n 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230,\r\n 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,\r\n 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,\r\n 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,\r\n 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0\r\n])\r\n\r\nvar TRI_TABLE = new Int32Array([\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,\r\n 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,\r\n 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1,\r\n 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1,\r\n 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1,\r\n 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1,\r\n 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1,\r\n 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1,\r\n 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1,\r\n 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1,\r\n 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1,\r\n 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,\r\n 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,\r\n 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,\r\n 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,\r\n 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,\r\n 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,\r\n 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,\r\n 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,\r\n 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,\r\n 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,\r\n 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,\r\n 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,\r\n 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,\r\n 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,\r\n 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,\r\n 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,\r\n 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,\r\n 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,\r\n 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,\r\n 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,\r\n 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,\r\n 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,\r\n 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,\r\n 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1,\r\n 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1,\r\n 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1,\r\n 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1,\r\n 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1,\r\n 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1,\r\n 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1,\r\n 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1,\r\n 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1,\r\n 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1,\r\n 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1,\r\n 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1,\r\n 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1,\r\n 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1,\r\n 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1,\r\n 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1,\r\n 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1,\r\n 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1,\r\n 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1,\r\n 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1,\r\n 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1,\r\n 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1,\r\n 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1,\r\n 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1,\r\n 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1,\r\n 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1,\r\n 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1,\r\n 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1,\r\n 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1,\r\n 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1,\r\n 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1,\r\n 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1,\r\n 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1,\r\n 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1,\r\n 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1,\r\n 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1,\r\n 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1,\r\n 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1,\r\n 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1,\r\n 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1,\r\n 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1,\r\n 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1,\r\n 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1,\r\n 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1,\r\n 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1,\r\n 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1,\r\n 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1,\r\n 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1,\r\n 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1,\r\n 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1,\r\n 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1,\r\n 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1,\r\n 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1,\r\n 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1,\r\n 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1,\r\n 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1,\r\n 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1,\r\n 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1,\r\n 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 3, 8, -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, -1, -1\r\n]);\r\n\r\nexport default {\r\n EDGE_TABLE: EDGE_TABLE,\r\n TRI_TABLE: TRI_TABLE\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cube_LUT.js","const THREE = require('three');\r\nimport {silverTexture} from './textures'\r\n\r\nimport Metaball from './metaball.js';\r\nimport InspectPoint from './inspect_point.js'\r\nimport LUT from './marching_cube_LUT.js';\r\nvar VISUAL_DEBUG = true;\r\nvar episolon = 0.1;\r\nvar balls = [];\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null};\r\n\r\n// lava\r\nvar l_mat = {\r\n uniforms: {\r\n texture: {type: \"t\",value: null},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/lava-vert.glsl'),\r\n fragmentShader: require('./shaders/lava-frag.glsl')\r\n};\r\n\r\nconst LAVA_MAT = new THREE.ShaderMaterial(l_mat);\r\nconst LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 });\r\nconst LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 });\r\nconst WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );\r\n\r\n// This function samples a point from the metaball's density function\r\n// Implement a function that returns the value of the all metaballs influence to a given point.\r\n// Please follow the resources given in the write-up for details.\r\nfunction sample(point) {\r\n var isovalue = 0.0;\r\n for (var i = 0; i < balls.length; i ++) {\r\n var r = balls[i].radius;\r\n var d = point.distanceTo(balls[i].pos);\r\n //isovalue += (r * r / (d * d)) * balls[i].neg;\r\n isovalue += (r * r / (d * d));\r\n }\r\n return isovalue;\r\n}\r\n\r\nexport default class MarchingCubes {\r\n\r\n constructor(App) {\r\n this.init(App);\r\n }\r\n\r\n init(App) {\r\n this.isPaused = false;\r\n VISUAL_DEBUG = App.config.visualDebug;\r\n\r\n // Initializing member variables.\r\n // Additional variables are used for fast computation.\r\n this.origin = new THREE.Vector3(0);\r\n\r\n this.isolevel = App.config.isolevel;\r\n this.minRadius = App.config.minRadius;\r\n this.maxRadius = App.config.maxRadius;\r\n\r\n this.gridCellWidth = App.config.gridCellWidth;\r\n this.gridCellHeight = App.config.gridCellHeight;\r\n this.gridCellDepth = App.config.gridCellDepth;\r\n this.halfCellWidth = App.config.gridCellWidth / 2.0;\r\n this.halfCellHeight = App.config.gridCellHeight / 2.0;\r\n this.halfCellDepth = App.config.gridCellDepth / 2.0;\r\n this.gridWidth = App.config.gridWidth;\r\n this.gridHeight = App.config.gridHeight;\r\n this.gridDepth = App.config.gridDepth;\r\n\r\n this.res = App.config.gridRes;\r\n this.res2 = App.config.gridRes * App.config.gridRes;\r\n this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes;\r\n\r\n this.maxSpeedX = App.config.maxSpeedX;\r\n this.maxSpeedY = App.config.maxSpeedY;\r\n this.maxSpeedZ = App.config.maxSpeedZ;\r\n this.numMetaballs = App.config.numMetaballs;\r\n\r\n this.camera = App.camera;\r\n this.scene = App.scene;\r\n\r\n this.voxels = [];\r\n //this.labels = [];\r\n this.balls = balls;\r\n\r\n this.showSpheres = true;\r\n this.showGrid = true;\r\n\r\n silverTexture.then(function(texture) {\r\n l_mat.uniforms.texture.value = texture;\r\n });\r\n\r\n if (App.config.material) {\r\n this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d});\r\n } else {\r\n this.material = App.config.material;\r\n }\r\n\r\n this.setupCells();\r\n this.setupMetaballs();\r\n this.makeMesh();\r\n };\r\n\r\n reset() {\r\n \tthis.scene.remove(this.mesh);\r\n \tthis.balls = []; balls = [];\r\n };\r\n\r\n // Convert from 1D index to 3D indices\r\n i1toi3(i1) {\r\n\r\n // [i % w, i % (h * w)) / w, i / (h * w)]\r\n\r\n // @note: ~~ is a fast substitute for Math.floor()\r\n return [\r\n i1 % this.res,\r\n ~~ ((i1 % this.res2) / this.res),\r\n ~~ (i1 / this.res2)\r\n ];\r\n };\r\n\r\n // Convert from 3D indices to 1 1D\r\n i3toi1(i3x, i3y, i3z) {\r\n\r\n // [x + y * w + z * w * h]\r\n\r\n return i3x + i3y * this.res + i3z * this.res2;\r\n };\r\n\r\n // Convert from 3D indices to 3D positions\r\n i3toPos(i3) {\r\n\r\n return new THREE.Vector3(\r\n i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth,\r\n i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight,\r\n i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth\r\n );\r\n };\r\n\r\n setupCells() {\r\n\r\n // Allocate voxels based on our grid resolution\r\n this.voxels = [];\r\n for (var i = 0; i < this.res3; i++) {\r\n var i3 = this.i1toi3(i);\r\n var {x, y, z} = this.i3toPos(i3);\r\n var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth);\r\n this.voxels.push(voxel);\r\n\r\n if (VISUAL_DEBUG) {\r\n this.scene.add(voxel.wireframe);\r\n this.scene.add(voxel.mesh);\r\n }\r\n }\r\n }\r\n\r\n setupMetaballs() {\r\n\r\n var x, y, z, vx, vy, vz, radius, pos, vel;\r\n var matLambertWhite = LAMBERT_WHITE;\r\n var maxRadiusTRippled = this.maxRadius * 3;\r\n var maxRadiusDoubled = this.maxRadius * 2;\r\n\r\n // Randomly generate metaballs with different sizes and velocities\r\n for (var i = 0; i < this.numMetaballs; i++) {\r\n x = this.gridWidth / 2;\r\n y = this.gridHeight / 2;\r\n z = this.gridDepth / 2;\r\n pos = new THREE.Vector3(3, 3, 3);\r\n\r\n vx = 0\r\n vy = (Math.random() * 2 - 1) * this.maxSpeedY/10;\r\n vz = 0\r\n vel = new THREE.Vector3(vx, vy, vz);\r\n\r\n radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius;\r\n var neg = 1;\r\n if (Math.random()>0.75) neg = -1;\r\n var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG);\r\n balls.push(ball);\r\n\r\n // if (VISUAL_DEBUG) {\r\n // this.scene.add(ball.mesh);\r\n // }\r\n }\r\n this.balls = balls;\r\n }\r\n\r\n update() {\r\n\r\n if (this.isPaused) {\r\n return;\r\n }\r\n\r\n // This should move the metaballs\r\n balls.forEach(function(ball) {\r\n ball.update();\r\n });\r\n this.balls = balls;\r\n\r\n for (var c = 0; c < this.res3; c++) { // every voxel\r\n\r\n // Sampling the center and vertex points\r\n this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos);\r\n for (var i = 0; i < 8; i ++) {\r\n this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos);\r\n }\r\n\r\n // Visualizing grid\r\n if (VISUAL_DEBUG && this.showGrid) {\r\n\r\n // Toggle voxels on or off\r\n if (this.voxels[c].center.isovalue > this.isolevel) {\r\n this.voxels[c].show();\r\n } else {\r\n this.voxels[c].hide();\r\n }\r\n this.voxels[c].center.updateLabel(this.camera);\r\n } else {\r\n this.voxels[c].center.clearLabel();\r\n }\r\n }\r\n\r\n this.updateMesh();\r\n }\r\n\r\n pause() {\r\n this.isPaused = true;\r\n }\r\n\r\n play() {\r\n this.isPaused = false;\r\n }\r\n\r\n show() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].show();\r\n }\r\n this.showGrid = true;\r\n };\r\n\r\n hide() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].hide();\r\n }\r\n this.showGrid = false;\r\n };\r\n\r\n makeMesh() {\r\n // @TODO\r\n var geo = new THREE.Geometry();\r\n this.mesh = new THREE.Mesh(geo, LAVA_MAT);\r\n this.mesh.geometry.dynamic = true;\r\n this.scene.add(this.mesh);\r\n }\r\n\r\n updateMesh() {\r\n // @TODO\r\n var vertices = [];\r\n var faces = [];\r\n var count = 0;\r\n for (var i = 0; i < this.res3; i ++) {\r\n var vox_count = 0;\r\n var vANDn = this.voxels[i].polygonize(this.isolevel);\r\n for (var j = 0; j < vANDn.vertPositions.length/3; j ++) {\r\n var normals = [];\r\n for (var k = 0; k < 3; k ++) {\r\n vertices.push(vANDn.vertPositions[vox_count]);\r\n normals.push(vANDn.vertNormals[vox_count]);\r\n vox_count++;\r\n count++;\r\n }\r\n faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals));\r\n }\r\n }\r\n this.mesh.geometry.vertices = vertices;\r\n //this.mesh.geometry.normals = normals;\r\n this.mesh.geometry.faces = faces;\r\n this.mesh.geometry.verticesNeedUpdate = true;\r\n this.mesh.geometry.normalsNeedUpdate = true;\r\n this.mesh.geometry.elementsNeedUpdate = true;\r\n this.mesh.geometry.computeFaceNormals();\r\n //console.log(this.mesh);\r\n }\r\n};\r\n\r\n// ------------------------------------------- //\r\n\r\nclass Voxel {\r\n\r\n constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.init(position, gridCellWidth, gridCellHeight, gridCellDepth);\r\n }\r\n\r\n init(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.pos = position;\r\n this.gridCellWidth = gridCellWidth;\r\n this.gridCellHeight = gridCellHeight;\r\n this.gridCellDepth = gridCellDepth;\r\n this.corners = [];\r\n\r\n if (VISUAL_DEBUG) {\r\n this.makeMesh();\r\n }\r\n\r\n this.makeInspectPoints();\r\n }\r\n\r\n makeMesh() {\r\n var halfGridCellWidth = this.gridCellWidth / 2.0;\r\n var halfGridCellHeight = this.gridCellHeight / 2.0;\r\n var halfGridCellDepth = this.gridCellDepth / 2.0;\r\n\r\n var positions = new Float32Array([\r\n // Front face\r\n halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n\r\n // Back face\r\n -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n ]);\r\n\r\n var indices = new Uint16Array([\r\n 0, 1, 2, 3,\r\n 4, 5, 6, 7,\r\n 0, 7, 7, 4,\r\n 4, 3, 3, 0,\r\n 1, 6, 6, 5,\r\n 5, 2, 2, 1\r\n ]);\r\n\r\n // Buffer geometry\r\n var geo = new THREE.BufferGeometry();\r\n geo.setIndex( new THREE.BufferAttribute( indices, 1 ) );\r\n geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\r\n\r\n // Wireframe line segments\r\n this.wireframe = new THREE.LineSegments( geo, WIREFRAME_MAT );\r\n this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n\r\n // Green cube\r\n geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth);\r\n this.mesh = new THREE.Mesh( geo, LAMBERT_GREEN );\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n\r\n makeInspectPoints() {\r\n var w = this.gridCellWidth / 2.0;\r\n var h = this.gridCellHeight / 2.0;\r\n var d = this.gridCellDepth / 2.0;\r\n var x = this.pos.x;\r\n var y = this.pos.y;\r\n var z = this.pos.z;\r\n var red = 0xff0000;\r\n\r\n // Center dot\r\n this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG);\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG));\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n if (this.wireframe) {\r\n this.wireframe.visible = true;\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n\r\n if (this.wireframe) {\r\n this.wireframe.visible = false;\r\n }\r\n\r\n if (this.center) {\r\n this.center.clearLabel();\r\n }\r\n }\r\n\r\n vertexLerp(isolevel, posA, posB) {\r\n var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue);\r\n var lerpPos = new THREE.Vector3();\r\n return lerpPos.lerpVectors(posA.pos, posB.pos, t);\r\n }\r\n\r\n // returns an array of points on the cube edges\r\n // null if no point exists for an edge\r\n edgePoints(edges, x) {\r\n var points = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]);\r\n if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]);\r\n if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]);\r\n if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]);\r\n if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]);\r\n if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]);\r\n if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]);\r\n if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]);\r\n if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]);\r\n if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]);\r\n if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]);\r\n if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]);\r\n return points;\r\n }\r\n\r\n getNormal(point) {\r\n var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z);\r\n var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z);\r\n var x = sample(x1) - sample(x0);\r\n var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z);\r\n var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z);\r\n var y = sample(y1) - sample(y0);\r\n var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon);\r\n var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon);\r\n var z = sample(z1) - sample(z0);\r\n var n = new THREE.Vector3(x,y,z);\r\n return n.normalize();\r\n }\r\n\r\n polygonize(isolevel) {\r\n\r\n var vertexList = [];\r\n var normalList = [];\r\n var faceList = [];\r\n\r\n // get corner vertices that are inside metaballs\r\n var corner = 1;\r\n var allVert = 0;\r\n for (var i = 0; i < 8; i ++) {\r\n if (this.corners[i].isovalue > isolevel) {\r\n allVert |= corner;\r\n }\r\n corner = corner << 1;\r\n }\r\n\r\n if (allVert != 0) {\r\n // get intersected edges\r\n var edges = LUT.EDGE_TABLE[allVert];\r\n\r\n // get 12 points\r\n var points = this.edgePoints(edges, isolevel);\r\n\r\n for (var j = 0; j < 16; j ++) {\r\n var tri = LUT.TRI_TABLE[allVert*16 + j];\r\n if (tri < 0) break;\r\n var vertex = points[tri];\r\n vertexList.push(vertex);\r\n normalList.push(this.getNormal(vertex));\r\n }\r\n }\r\n\r\n\r\n return {\r\n vertPositions: vertexList,\r\n vertNormals: normalList\r\n };\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cubes.js","const THREE = require('three')\r\n\r\nvar SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32);\r\nvar LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 });\r\n\r\nexport default class Metaball {\r\n constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug);\r\n }\r\n\r\n init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.gridWidth = gridWidth;\r\n this.gridHeight = gridHeight;\r\n this.gridDepth = gridDepth;\r\n this.pos = pos;\r\n this.vel = vel;\r\n this.neg = neg;\r\n this.radius = radius;\r\n this.radius2 = radius * radius;\r\n this.mesh = null;\r\n this.debug = visualDebug;\r\n // if (visualDebug) {\r\n // this.makeMesh();\r\n // }\r\n }\r\n\r\n makeMesh() {\r\n this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE);\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n this.mesh.scale.set(this.radius, this.radius, this.radius);\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n };\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n };\r\n\r\n update() {\r\n\r\n // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z);\r\n // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir);\r\n // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2));\r\n // if ((dist + 2*this.radius) > this.gridWidth \r\n // || (dist + 2*this.radius) > this.gridDepth) {\r\n // this.vel.add(disp);\r\n // }\r\n var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0;\r\n if (y) this.vel.y *= -1;\r\n \r\n var date = new Date();\r\n var velocity = new THREE.Vector3();\r\n velocity.copy(this.vel).multiplyScalar(3);\r\n this.pos.add(velocity);\r\n\r\n \r\n\r\n \r\n // if (x || y || z) {\r\n // this.vel.multiplyScalar(-1);\r\n // }\r\n if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/metaball.js","const THREE = require('three');\r\n\r\nconst POINT_MATERIAL = new THREE.PointsMaterial( { color: 0xee1111, size: 10, sizeAttenuation: true } );\r\n\r\nexport default class InspectPoint {\r\n\r\n constructor(pos, isovalue, visualDebug) {\r\n this.init(pos, isovalue, visualDebug);\r\n }\r\n\r\n init(pos, isovalue, visualDebug) {\r\n this.pos = pos;\r\n this.isovalue = isovalue;\r\n this.label = null;\r\n\r\n if (visualDebug) {\r\n this.makeLabel();\r\n }\r\n };\r\n\r\n // Create an HTML div for holding label\r\n makeLabel() {\r\n this.label = document.createElement('div');\r\n this.label.style.position = 'absolute';\r\n this.label.style.width = 100;\r\n this.label.style.height = 100;\r\n this.label.style.userSelect = 'none';\r\n this.label.style.cursor = 'default';\r\n this.label.style.fontSize = '0.3em';\r\n this.label.style.pointerEvents = 'none';\r\n document.body.appendChild(this.label); \r\n };\r\n\r\n updateLabel(camera) {\r\n if (this.label) {\r\n var screenPos = this.pos.clone().project(camera);\r\n screenPos.x = ( screenPos.x + 1 ) / 2 * window.innerWidth;;\r\n screenPos.y = - ( screenPos.y - 1 ) / 2 * window.innerHeight;;\r\n\r\n this.label.style.top = screenPos.y + 'px';\r\n this.label.style.left = screenPos.x + 'px';\r\n this.label.innerHTML = this.isovalue.toFixed(2);\r\n this.label.style.opacity = this.isovalue - 0.5; \r\n }\r\n };\r\n\r\n clearLabel() {\r\n if (this.label) {\r\n this.label.innerHTML = '';\r\n this.label.style.opacity = 0;\r\n }\r\n };\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/inspect_point.js","module.exports = \"\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normalMatrix * normal;\\r\\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\nuniform sampler2D texture;\\r\\nuniform vec3 u_ambient;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 ref = reflect(e_position, f_normal);\\r\\n\\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\\r\\n float x = f_normal.x/m + 0.5;\\r\\n float y = f_normal.y/m + 0.5;\\r\\n\\r\\n vec4 color = texture2D(texture, vec2(x,y));\\r\\n\\r\\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","'use strict';\n\nmodule.exports = function (THREE) {\n\n /**\n * @author mrdoob / http://mrdoob.com/\n */\n THREE.OBJLoader = function (manager) {\n\n this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;\n };\n\n THREE.OBJLoader.prototype = {\n\n constructor: THREE.OBJLoader,\n\n load: function load(url, onLoad, onProgress, onError) {\n\n var scope = this;\n\n var loader = new THREE.XHRLoader(scope.manager);\n loader.load(url, function (text) {\n\n onLoad(scope.parse(text));\n }, onProgress, onError);\n },\n\n parse: function parse(text) {\n\n console.time('OBJLoader');\n\n var object,\n objects = [];\n var geometry, material;\n\n function parseVertexIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3;\n }\n\n function parseNormalIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + normals.length / 3) * 3;\n }\n\n function parseUVIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2;\n }\n\n function addVertex(a, b, c) {\n\n geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]);\n }\n\n function addNormal(a, b, c) {\n\n geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]);\n }\n\n function addUV(a, b, c) {\n\n geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]);\n }\n\n function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\n var ia = parseVertexIndex(a);\n var ib = parseVertexIndex(b);\n var ic = parseVertexIndex(c);\n var id;\n\n if (d === undefined) {\n\n addVertex(ia, ib, ic);\n } else {\n\n id = parseVertexIndex(d);\n\n addVertex(ia, ib, id);\n addVertex(ib, ic, id);\n }\n\n if (ua !== undefined) {\n\n ia = parseUVIndex(ua);\n ib = parseUVIndex(ub);\n ic = parseUVIndex(uc);\n\n if (d === undefined) {\n\n addUV(ia, ib, ic);\n } else {\n\n id = parseUVIndex(ud);\n\n addUV(ia, ib, id);\n addUV(ib, ic, id);\n }\n }\n\n if (na !== undefined) {\n\n ia = parseNormalIndex(na);\n ib = parseNormalIndex(nb);\n ic = parseNormalIndex(nc);\n\n if (d === undefined) {\n\n addNormal(ia, ib, ic);\n } else {\n\n id = parseNormalIndex(nd);\n\n addNormal(ia, ib, id);\n addNormal(ib, ic, id);\n }\n }\n }\n\n // create mesh if no objects in text\n\n if (/^o /gm.test(text) === false) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: '',\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n }\n\n var vertices = [];\n var normals = [];\n var uvs = [];\n\n // v float float float\n\n var vertex_pattern = /v( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vn float float float\n\n var normal_pattern = /vn( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vt float float\n\n var uv_pattern = /vt( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // f vertex vertex vertex ...\n\n var face_pattern1 = /f( +-?\\d+)( +-?\\d+)( +-?\\d+)( +-?\\d+)?/;\n\n // f vertex/uv vertex/uv vertex/uv ...\n\n var face_pattern2 = /f( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...\n\n var face_pattern3 = /f( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex//normal vertex//normal vertex//normal ...\n\n var face_pattern4 = /f( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))?/;\n\n //\n\n var lines = text.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n\n var line = lines[i];\n line = line.trim();\n\n var result;\n\n if (line.length === 0 || line.charAt(0) === '#') {\n\n continue;\n } else if ((result = vertex_pattern.exec(line)) !== null) {\n\n // [\"v 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = normal_pattern.exec(line)) !== null) {\n\n // [\"vn 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = uv_pattern.exec(line)) !== null) {\n\n // [\"vt 0.1 0.2\", \"0.1\", \"0.2\"]\n\n uvs.push(parseFloat(result[1]), parseFloat(result[2]));\n } else if ((result = face_pattern1.exec(line)) !== null) {\n\n // [\"f 1 2 3\", \"1\", \"2\", \"3\", undefined]\n\n addFace(result[1], result[2], result[3], result[4]);\n } else if ((result = face_pattern2.exec(line)) !== null) {\n\n // [\"f 1/1 2/2 3/3\", \" 1/1\", \"1\", \"1\", \" 2/2\", \"2\", \"2\", \" 3/3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]);\n } else if ((result = face_pattern3.exec(line)) !== null) {\n\n // [\"f 1/1/1 2/2/2 3/3/3\", \" 1/1/1\", \"1\", \"1\", \"1\", \" 2/2/2\", \"2\", \"2\", \"2\", \" 3/3/3\", \"3\", \"3\", \"3\", undefined, undefined, undefined, undefined]\n\n addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]);\n } else if ((result = face_pattern4.exec(line)) !== null) {\n\n // [\"f 1//1 2//2 3//3\", \" 1//1\", \"1\", \"1\", \" 2//2\", \"2\", \"2\", \" 3//3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]);\n } else if (/^o /.test(line)) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: line.substring(2).trim(),\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n } else if (/^g /.test(line)) {\n\n // group\n\n } else if (/^usemtl /.test(line)) {\n\n // material\n\n material.name = line.substring(7).trim();\n } else if (/^mtllib /.test(line)) {\n\n // mtl file\n\n } else if (/^s /.test(line)) {\n\n // smooth shading\n\n } else {\n\n // console.log( \"THREE.OBJLoader: Unhandled line \" + line );\n\n }\n }\n\n var container = new THREE.Object3D();\n var l;\n\n for (i = 0, l = objects.length; i < l; i++) {\n\n object = objects[i];\n geometry = object.geometry;\n\n var buffergeometry = new THREE.BufferGeometry();\n\n buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3));\n\n if (geometry.normals.length > 0) {\n\n buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3));\n }\n\n if (geometry.uvs.length > 0) {\n\n buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2));\n }\n\n material = new THREE.MeshLambertMaterial({\n color: 0xff0000\n });\n material.name = object.material.name;\n\n var mesh = new THREE.Mesh(buffergeometry, material);\n mesh.name = object.name;\n\n container.add(mesh);\n }\n\n console.timeEnd('OBJLoader');\n\n return container;\n }\n\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-obj-loader/dist/index.js\n// module id = 17\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n e_position = cameraPosition;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-vert.glsl\n// module id = 18\n// module chunks = 0","module.exports = \"#define M_PI 3.1415926535897932384626433832795\\r\\n\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nfloat cosine(float a, float b, float c, float d, float t) {\\r\\n\\treturn a + b * cos(2.0 * M_PI * (c * t + d));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\\r\\n\\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\\r\\n\\r\\n gl_FragColor = vec4(d,d,d, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-frag.glsl\n// module id = 19\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-vert.glsl\n// module id = 20\n// module chunks = 0","module.exports = \"uniform vec3 u_lightPos;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\\r\\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\\r\\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-frag.glsl\n// module id = 21\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/glass-5b14a7.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/glass.obj\n// module id = 22\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/lamp-1bcc16.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/lamp.obj\n// module id = 23\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 0521d17e9dc7179e2918","webpack:///./src/main.js","webpack:///./src/textures.js","webpack:///./~/three/build/three.js","webpack:///./src/assets/silver.bmp","webpack:///./src/framework.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/three-orbit-controls/index.js","webpack:///./src/marching_cube_LUT.js","webpack:///./src/marching_cubes.js","webpack:///./src/metaball.js","webpack:///./src/inspect_point.js","webpack:///./src/shaders/lava-vert.glsl","webpack:///./src/shaders/lava-frag.glsl","webpack:///./index.html","webpack:///./~/three-obj-loader/dist/index.js","webpack:///./src/shaders/glass-vert.glsl","webpack:///./src/shaders/glass-frag.glsl","webpack:///./src/shaders/metal-vert.glsl","webpack:///./src/shaders/metal-frag.glsl","webpack:///./src/assets/glass.obj","webpack:///./src/assets/lamp.obj"],"names":["require","THREE","OBJLoader","DEFAULT_VISUAL_DEBUG","DEFAULT_ISO_LEVEL","DEFAULT_GRID_RES","DEFAULT_GRID_WIDTH","DEFAULT_GRID_HEIGHT","DEFAULT_GRID_DEPTH","DEFAULT_NUM_METABALLS","DEFAULT_MIN_RADIUS","DEFAULT_MAX_RADIUS","DEFAULT_MAX_SPEEDX","DEFAULT_MAX_SPEEDY","options","lightColor","lightIntensity","ambient","albedo","loaded","red","Color","green","glassGeo","lampGeo","g_mat","uniforms","u_albedo","type","value","u_ambient","u_lightCol","u_lightIntensity","vertexShader","fragmentShader","m_mat","GLASS_MAT","MeshLambertMaterial","color","emissive","transparent","opacity","METAL_MAT","MeshPhongMaterial","App","marchingCubes","undefined","config","visualDebug","isolevel","gridRes","gridWidth","gridHeight","gridDepth","gridCellWidth","gridCellHeight","gridCellDepth","numMetaballs","minRadius","maxRadius","maxSpeedX","maxSpeedY","maxSpeedZ","camera","scene","renderer","isPaused","onLoad","framework","gui","stats","setClearColor","objLoader","obj","load","children","geometry","glass","Mesh","translateX","translateZ","add","lamp","setupCamera","setupLights","setupScene","setupGUI","cosine","a","b","c","d","t","Math","cos","PI","onUpdate","date","Date","sec","getSeconds","r","g","set","update","position","lookAt","Vector3","directionalLight","DirectionalLight","setHSL","multiplyScalar","step","onChange","reset","init","silverTexture","Promise","resolve","reject","TextureLoader","texture","OrbitControls","callback","setMode","domElement","style","left","top","document","body","appendChild","GUI","window","addEventListener","Scene","PerspectiveCamera","innerWidth","innerHeight","WebGLRenderer","antialias","alpha","setPixelRatio","devicePixelRatio","setSize","controls","enableDamping","enableZoom","target","rotateSpeed","zoomSpeed","panSpeed","hasMoved","aspect","updateProjectionMatrix","tick","begin","render","end","requestAnimationFrame","EDGE_TABLE","Int32Array","TRI_TABLE","VISUAL_DEBUG","episolon","balls","l_mat","LAVA_MAT","ShaderMaterial","LAMBERT_WHITE","LAMBERT_GREEN","MeshBasicMaterial","WIREFRAME_MAT","LineBasicMaterial","linewidth","sample","point","isovalue","i","length","radius","distanceTo","pos","MarchingCubes","origin","halfCellWidth","halfCellHeight","halfCellDepth","res","res2","res3","voxels","showSpheres","showGrid","then","material","setupCells","setupMetaballs","makeMesh","remove","mesh","i1","i3x","i3y","i3z","i3","x","y","z","i1toi3","i3toPos","voxel","Voxel","push","wireframe","vx","vy","vz","vel","matLambertWhite","maxRadiusTRippled","maxRadiusDoubled","random","neg","ball","forEach","center","corners","show","hide","updateLabel","clearLabel","updateMesh","geo","Geometry","dynamic","vertices","faces","count","vox_count","vANDn","polygonize","j","vertPositions","normals","k","vertNormals","Face3","verticesNeedUpdate","normalsNeedUpdate","elementsNeedUpdate","computeFaceNormals","makeInspectPoints","halfGridCellWidth","halfGridCellHeight","halfGridCellDepth","positions","Float32Array","indices","Uint16Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","BoxBufferGeometry","w","h","visible","posA","posB","lerpPos","lerpVectors","edges","points","vertexLerp","x0","x1","y0","y1","z0","z1","n","normalize","vertexList","normalList","faceList","corner","allVert","edgePoints","tri","vertex","getNormal","SPHERE_GEO","SphereBufferGeometry","Metaball","radius2","debug","scale","velocity","copy","POINT_MATERIAL","PointsMaterial","size","sizeAttenuation","InspectPoint","label","makeLabel","createElement","width","height","userSelect","cursor","fontSize","pointerEvents","screenPos","clone","project","innerHTML","toFixed"],"mappings":"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A;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;A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;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;;AAEA;;AAEA;AACA;AACA,uDAAsD;;AAEtD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AA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AAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;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BAA0B,wBAAwB,8CAA8C,qCAAqC,wCAAwC,6BAA6B,8CAA8C,swBAAswB,wFAAwF,yGAAyG,0CAA0C,qnBAAqnB,yDAAyD,6IAA6I;;AAEvpE,wEAAuE,8CAA8C,gYAAgY,iTAAiT,+QAA+Q,gEAAgE;;AAErnC,2CAA0C,uBAAuB,sIAAsI,sGAAsG,sCAAsC;;AAEnV,0CAAyC,kJAAkJ,iDAAiD,kKAAkK;;AAE9Y,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,8KAA8K,wKAAwK,mCAAmC,gJAAgJ;;AAEtkB,2CAA0C,yKAAyK,+EAA+E,GAAG;;AAErS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,0DAAyD;AACzD,0CAAyC;AACzC,0CAAyC;;AAEzC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,eAAc,YAAY;;AAE1B;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;;AAE1B,UAAS,cAAc;AACvB,mBAAkB,mCAAmC;;AAErD,kBAAiB,cAAc;AAC/B,eAAc,cAAc;;AAE5B,aAAY,cAAc;AAC1B,iBAAgB,aAAa;AAC7B,mBAAkB,aAAa;AAC/B,sBAAqB;;AAErB,IAAG;;AAEH;;AAEA,YAAW,cAAc;AACzB,qBAAoB;;AAEpB,IAAG;;AAEH;;AAEA,eAAc,cAAc;AAC5B,wBAAuB;;AAEvB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,cAAa,cAAc;AAC3B,gBAAe;;AAEf,IAAG;;AAEH;;AAEA,gBAAe,cAAc;AAC7B,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,sBAAqB,cAAc;AACnC,wBAAuB,WAAW;AAClC,uBAAsB;;AAEtB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,iBAAgB,iBAAiB;AACjC,cAAa,WAAW;AACxB,aAAY,cAAc;AAC1B,eAAc;;AAEd,IAAG;;AAEH;;AAEA,wBAAuB,YAAY;;AAEnC,wBAAuB;AACvB,kBAAiB;AACjB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,2BAA0B,YAAY;AACtC,8BAA6B,YAAY;;AAEzC,iBAAgB;AAChB,cAAa;AACb,iBAAgB;AAChB,kBAAiB;AACjB,iBAAgB;AAChB,gBAAe;AACf,oBAAmB;AACnB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,oBAAmB,YAAY;AAC/B,uBAAsB,YAAY;;AAElC,kBAAiB;AACjB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb,iBAAgB;;AAEhB,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,qBAAoB,YAAY;AAChC,wBAAuB,YAAY;;AAEnC,uBAAsB;AACtB,kBAAiB;AACjB,iBAAgB;AAChB;AACA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;AAC1B,WAAU,aAAa;AACvB,YAAW,aAAa;AACxB,UAAS,cAAc;AACvB,mBAAkB;;AAElB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB,+BAA+B;AAChD,kBAAiB,+BAA+B;AAChD,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB,+BAA+B;AAChD,kBAAiB,aAAa;AAC9B,kBAAiB,WAAW;AAC5B,yBAAwB,WAAW;AACnC;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA,kBAAiB,WAAW;AAC5B,kBAAiB,WAAW;AAC5B,kBAAiB;AACjB;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,gBAAe;;AAEf,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,aAAY,cAAc;AAC1B,aAAY,aAAa;AACzB,eAAc;AACd,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,cAAc;AAC9B,aAAY;AACZ,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,gBAAe;;AAEf,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,iBAAgB,WAAW;AAC3B,0BAAyB;AACzB;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mCAAkC;;AAElC,mCAAkC;AAClC,0BAAyB;AACzB,8BAA6B;;AAE7B,sCAAqC;;AAErC,+BAA8B;AAC9B,yBAAwB;;AAExB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB,iBAAgB;;AAEhB,4BAA2B;;AAE3B,gCAA+B;;AAE/B,uEAAsE;AACtE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;;AAElE,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD,6EAA4E;AAC5E,6EAA4E;;AAE5E,SAAQ;;AAER,4FAA2F;;AAE3F,QAAO;;AAEP;;AAEA;;AAEA,mCAAkC;;AAElC,6BAA4B;AAC5B,6BAA4B;AAC5B,0BAAyB;;AAEzB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB;;AAEA,gCAA+B;;AAE/B,mDAAkD;;AAElD;;AAEA,SAAQ,8BAA8B;;AAEtC,8CAA6C;;AAE7C;;AAEA,SAAQ,OAAO;;AAEf,8CAA6C;AAC7C,4CAA2C;AAC3C,gCAA+B;AAC/B,mCAAkC;;AAElC,SAAQ;;AAER,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;AACA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;;AAGA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sDAAqD;;AAErD,mCAAkC;AAClC,oCAAmC;AACnC,6BAA4B;AAC5B,yBAAwB;AACxB,4BAA2B;AAC3B,2BAA0B;;AAE1B,8BAA6B;AAC7B,wBAAuB;;AAEvB,uBAAsB;;AAEtB,mBAAkB;;AAElB,qCAAoC;;AAEpC,+CAA8C;;AAE9C,4BAA2B;AAC3B,qGAAoG;AACpG,qGAAoG;;AAEpG,0BAAyB;;AAEzB,oEAAmE;AACnE,2CAA0C;AAC1C,wDAAuD;;AAEvD,mCAAkC;;AAElC,OAAM;;AAEN;;AAEA;;AAEA,sDAAqD;;AAErD,yBAAwB;AACxB,4BAA2B;AAC3B,4BAA2B;;AAE3B,0BAAyB;AACzB,4BAA2B;AAC3B,+BAA8B;AAC9B,4BAA2B;AAC3B,2BAA0B;AAC1B,8BAA6B;;AAE7B,uBAAsB;;AAEtB,mBAAkB;;AAElB,4CAA2C;;AAE3C,4CAA2C;;AAE3C,uEAAsE;;AAEtE,2BAA0B;;AAE1B,sDAAqD;AACrD,8BAA6B;;AAE7B,6BAA4B;;AAE5B,0DAAyD;;AAEzD,SAAQ,OAAO;;AAEf,qCAAoC;AACpC,8EAA6E;AAC7E,wDAAuD;;AAEvD,SAAQ;;AAER,wFAAuF;;AAEvF,QAAO;;AAEP,OAAM;;AAEN;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gCAA+B;AAC/B,gCAA+B;;AAE/B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,yBAAwB;;AAExB;AACA;AACA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA,kBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,2CAA0C;;AAE1C;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB,SAAS;AAC7B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,iBAAiB;;AAEzC,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA,8BAA6B,kBAAkB;;AAE/C;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,iBAAgB,gBAAgB,aAAa,iBAAiB,YAAY,EAAE;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qCAAoC,6EAA6E,GAAG;AACpH,uCAAsC,8CAA8C,GAAG;;AAEvF;;AAEA;AACA;;AAEA,oBAAmB;AACnB,uBAAsB;AACtB,yBAAwB;;AAExB,yBAAwB;AACxB,6BAA4B;AAC5B,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAqC,OAAO;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C,QAAQ;;AAErD;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;;AAEjF;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;;AAEhC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,iCAAgC,YAAY;;AAE5C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,iCAAgC,YAAY;;AAE5C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;;AAEjC;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;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;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK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;;AAE/C;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AA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A;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AA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AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAE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B;;AAEtC,oBAAmB,mBAAmB;;AAEtC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,kBAAkB;;AAEhC,gBAAe,oBAAoB;;AAEnC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,eAAc,iBAAiB;;AAE/B;;AAEA,gBAAe,mBAAmB;;AAElC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;AACA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;AACA;;AAE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A;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AA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D;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,0FAAyF,4CAA4C;AACrI;;AAEA;AACA;AACA,8FAA6F,4CAA4C;AACzI;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP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A;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;AACzB,gCAA+B;;AAE/B;AACA;AACA,qCAAoC;AACpC,mCAAkC;;AAElC;AACA;AACA;AACA;;AAEA,uDAAsD;AACtD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAAyB;;AAEzB;AACA;AACA;AACA,8BAA6B;;AAE7B;AACA;;AAEA;AACA,gBAAe;;AAEf;AACA,wBAAuB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4BAA2B,kBAAkB,GAAG;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA,sBAAqB;AACrB,qBAAoB;AACpB,mBAAkB;;AAElB,gBAAe;;AAEf;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,8CAA6C;AAC7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA,gDAA+C;;AAE/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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0521d17e9dc7179e2918","require('file-loader?name=[name].[ext]!../index.html');\r\nimport {silverTexture} from './textures'\r\n//import {quote} from './quote'\r\n// Credit:\r\n// http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/\r\n// http://paulbourke.net/geometry/polygonise/\r\n\r\nconst THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much\r\nconst OBJLoader = require('three-obj-loader');\r\nOBJLoader(THREE)\r\n\r\nimport Framework from './framework'\r\nimport LUT from './marching_cube_LUT.js'\r\nimport MarchingCubes from './marching_cubes.js'\r\n\r\nconst DEFAULT_VISUAL_DEBUG = false;\r\nconst DEFAULT_ISO_LEVEL = 1.0;\r\nconst DEFAULT_GRID_RES = 30;\r\nconst DEFAULT_GRID_WIDTH = 6;\r\nconst DEFAULT_GRID_HEIGHT = 17;\r\nconst DEFAULT_GRID_DEPTH = 6;\r\nconst DEFAULT_NUM_METABALLS = 7;\r\nconst DEFAULT_MIN_RADIUS = 0.5;\r\nconst DEFAULT_MAX_RADIUS = 1;\r\nconst DEFAULT_MAX_SPEEDX = 0.005;\r\nconst DEFAULT_MAX_SPEEDY = 0.3;\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111', albedo: '#110000'};\r\nvar loaded = false;\r\nvar red = new THREE.Color(1.0,0.0,0.0);\r\nvar green = new THREE.Color(0.0,1.0,0.0);\r\nvar glassGeo;\r\nvar lampGeo;\r\n\r\n// glass, emissive, iridescent\r\nvar g_mat = {\r\n uniforms: {\r\n u_albedo: {type: 'v3', value: new THREE.Color(options.albedo)},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/glass-vert.glsl'),\r\n fragmentShader: require('./shaders/glass-frag.glsl')\r\n};\r\n\r\n// metal\r\nvar m_mat = {\r\n uniforms: {\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/metal-vert.glsl'),\r\n fragmentShader: require('./shaders/metal-frag.glsl')\r\n};\r\n\r\n//const GLASS_MAT = new THREE.ShaderMaterial(g_mat);\r\nvar GLASS_MAT = new THREE.MeshLambertMaterial({ color: 0xffffff, emissive: 0xff0000, transparent: true, opacity: 0.3});\r\nvar METAL_MAT = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x111111});\r\n\r\nvar App = {\r\n //\r\n marchingCubes: undefined,\r\n config: {\r\n // Global control of all visual debugging.\r\n // This can be set to false to disallow any memory allocation of visual debugging components.\r\n // **Note**: If your application experiences performance drop, disable this flag.\r\n visualDebug: DEFAULT_VISUAL_DEBUG,\r\n\r\n // The isolevel for marching cubes\r\n isolevel: DEFAULT_ISO_LEVEL,\r\n\r\n // Grid resolution in each dimension. If gridRes = 4, then we have a 4x4x4 grid\r\n gridRes: DEFAULT_GRID_RES,\r\n\r\n // Total width of grid\r\n gridWidth: DEFAULT_GRID_WIDTH,\r\n\r\n gridHeight: DEFAULT_GRID_HEIGHT,\r\n\r\n gridDepth: DEFAULT_GRID_DEPTH,\r\n\r\n // Width of each voxel\r\n // Ideally, we want the voxel to be small (higher resolution)\r\n gridCellWidth: DEFAULT_GRID_WIDTH / DEFAULT_GRID_RES,\r\n gridCellHeight: DEFAULT_GRID_HEIGHT / DEFAULT_GRID_RES,\r\n gridCellDepth: DEFAULT_GRID_DEPTH / DEFAULT_GRID_RES,\r\n\r\n // Number of metaballs\r\n numMetaballs: DEFAULT_NUM_METABALLS,\r\n\r\n // Minimum radius of a metaball\r\n minRadius: DEFAULT_MIN_RADIUS,\r\n\r\n // Maxium radius of a metaball\r\n maxRadius: DEFAULT_MAX_RADIUS,\r\n\r\n // Maximum speed of a metaball\r\n maxSpeedX: DEFAULT_MAX_SPEEDX,\r\n maxSpeedY: DEFAULT_MAX_SPEEDY,\r\n maxSpeedZ: DEFAULT_MAX_SPEEDX, \r\n },\r\n\r\n // Scene's framework objects\r\n camera: undefined,\r\n scene: undefined,\r\n renderer: undefined,\r\n\r\n // Play/pause control for the simulation\r\n isPaused: false,\r\n color: 0xffffff\r\n};\r\n\r\n// called after the scene loads\r\nfunction onLoad(framework) {\r\n\r\n var {scene, camera, renderer, gui, stats} = framework;\r\n App.scene = scene;\r\n App.camera = camera;\r\n App.renderer = renderer;\r\n\r\n renderer.setClearColor( 0x111111 );\r\n //scene.add(new THREE.AxisHelper(20));\r\n\r\n var objLoader = new THREE.OBJLoader();\r\n var obj = objLoader.load(require('./assets/glass.obj'), function(obj) {\r\n glassGeo = obj.children[0].geometry;\r\n var glass = new THREE.Mesh(glassGeo, GLASS_MAT);\r\n glass.translateX(-1.5);\r\n glass.translateZ(-1.5);\r\n App.scene.add(glass);\r\n loaded = true;\r\n });\r\n\r\n var obj = objLoader.load(require('./assets/lamp.obj'), function(obj) {\r\n lampGeo = obj.children[0].geometry;\r\n var lamp = new THREE.Mesh(lampGeo, METAL_MAT);\r\n lamp.translateX(-1.5);\r\n lamp.translateZ(-1.5);\r\n App.scene.add(lamp);\r\n });\r\n\r\n setupCamera(App.camera);\r\n setupLights(App.scene);\r\n setupScene(App.scene);\r\n setupGUI(gui);\r\n}\r\n\r\nfunction cosine(a,b,c,d,t) {\r\n return a + b * Math.cos(2.0 * Math.PI * (c * t + d));\r\n}\r\n\r\n// called on frame updates\r\nfunction onUpdate(framework) {\r\n if (loaded) {\r\n var date = new Date();\r\n var sec = date.getSeconds();\r\n var r = cosine(0.5, 0.5, 1.0, 0.0, sec/60.0);\r\n var g = cosine(0.5, 0.5, 1.0, 0.33, sec/60.0);\r\n var b = cosine(0.5, 0.5, 1.0, 0.67, sec/60.0); \r\n GLASS_MAT.emissive.set(new THREE.Color(r,g,b));\r\n }\r\n if (App.marchingCubes) {\r\n App.marchingCubes.update();\r\n }\r\n}\r\n\r\nfunction setupCamera(camera) {\r\n // set camera position\r\n camera.position.set(25, 10, 25);\r\n camera.lookAt(new THREE.Vector3(1,0,1));\r\n}\r\n\r\nfunction setupLights(scene) {\r\n\r\n // Directional light\r\n var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );\r\n directionalLight.color.setHSL(0.1, 1, 0.95);\r\n directionalLight.position.set(1, 10, 2);\r\n directionalLight.position.multiplyScalar(10);\r\n\r\n scene.add(directionalLight);\r\n}\r\n\r\nfunction setupScene(scene) {\r\n App.marchingCubes = new MarchingCubes(App);\r\n}\r\n\r\nfunction setupGUI(gui) {\r\n\r\n // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage\r\n\r\n gui.add(App.config, 'numMetaballs', 1, 10).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'minRadius', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxRadius', 1, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'maxSpeedY', 0, 1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'isolevel', 0, 2).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n gui.add(App.config, 'gridRes', 1, 40).step(1).onChange(function(value) {\r\n App.marchingCubes.reset();\r\n App.marchingCubes = new MarchingCubes(App);\r\n });\r\n\r\n\r\n}\r\n\r\n// when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate\r\nFramework.init(onLoad, onUpdate);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n// this file is just for convenience. it sets up loading the mario obj and texture\r\n\r\nconst THREE = require('three');\r\n\r\nexport var silverTexture = new Promise((resolve, reject) => {\r\n (new THREE.TextureLoader()).load(require('./assets/silver.bmp'), function(texture) {\r\n resolve(texture);\r\n })\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/textures.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*(\\S*)\\s*\\(/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tObject.assign( EventDispatcher.prototype, {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\tvar REVISION = '82';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar BlendingMode = {\n\t\tNoBlending: NoBlending,\n\t\tNormalBlending: NormalBlending,\n\t\tAdditiveBlending: AdditiveBlending,\n\t\tSubtractiveBlending: SubtractiveBlending,\n\t\tMultiplyBlending: MultiplyBlending,\n\t\tCustomBlending: CustomBlending\n\t};\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar TextureMapping = {\n\t\tUVMapping: UVMapping,\n\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t};\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar TextureWrapping = {\n\t\tRepeatWrapping: RepeatWrapping,\n\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t};\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar TextureFilter = {\n\t\tNearestFilter: NearestFilter,\n\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\tLinearFilter: LinearFilter,\n\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t};\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\trandom16: function () {\n\n\t\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\t\treturn Math.random();\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: TextureIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.sourceFile = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\tvar count = 0;\n\tfunction TextureIdCount() { return count++; }\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\t\t\tthis.w = attribute.array[ index + 3 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\t\t\t\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyProjection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 projection matrix\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\t\t\tvar d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide\n\n\t\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * d;\n\t\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * d;\n\t\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * d;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyProjection( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tindex = index * attribute.itemSize + offset;\n\n\t\t\tthis.x = attribute.array[ index ];\n\t\t\tthis.y = attribute.array[ index + 1 ];\n\t\t\tthis.z = attribute.array[ index + 2 ];\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix4( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeFrustum: function ( left, right, bottom, top, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakePerspective: function ( fov, aspect, near, far ) {\n\n\t\t\tvar ymax = near * Math.tan( _Math.DEG2RAD * fov * 0.5 );\n\t\t\tvar ymin = - ymax;\n\t\t\tvar xmin = ymin * aspect;\n\t\t\tvar xmax = ymax * aspect;\n\n\t\t\treturn this.makeFrustum( xmin, xmax, ymin, ymax, near, far );\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\\n\\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\\n}\\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\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}\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\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}\\n\";\n\n\tvar 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\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n return value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n float maxComponent = max( max( value.r, value.g ), value.b );\\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n M = ceil( M * 255.0 ) / 255.0;\\n return vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n float maxRGB = max( value.x, max( value.g, value.b ) );\\n float D = max( maxRange / maxRGB, 1.0 );\\n D = min( floor( D ) / 255.0, 1.0 );\\n return 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 vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n vec4 vResult;\\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n vResult.w = fract(Le);\\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n return 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 float Le = value.z * 255.0 + value.w;\\n vec3 Xp_Y_XYZp;\\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n return vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntenstiy;\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\\n\\t#else\\n\\t\\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\\n\\t#endif\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\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\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\\n\\t\\t\\tdirectLight.color = pointLight.color;\\n\\t\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.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_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 ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\\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_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\\t#include \\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = flipNormal * 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 = flipNormal * 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\\t#include \\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 = flipNormal * 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 = flipNormal * 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( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * 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 = flipNormal * 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\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar 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};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial 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\\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_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar 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\";\n\n\tvar 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}\\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_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\";\n\n\tvar 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 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\\t\\t\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n return normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n return 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 return ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n return linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar 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\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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 boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n return toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n return 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 color *= toneMappingExposure;\\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n color *= toneMappingExposure;\\n color = max( vec3( 0.0 ), color - 0.004 );\\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar 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\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar 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\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\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\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\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\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight;\\n\\treflectedLight.directDiffuse = vec3( 0.0 );\\n\\treflectedLight.directSpecular = vec3( 0.0 );\\n\\treflectedLight.indirectDiffuse = diffuseColor.rgb;\\n\\treflectedLight.indirectSpecular = vec3( 0.0 );\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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 \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\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 \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar 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\\nuniform float envMapIntensity;\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"uniform float opacity;\\nvarying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\\n\\t#include \\n}\\n\";\n\n\tvar normal_vert = \"varying vec3 vNormal;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvNormal = normalize( normalMatrix * normal );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\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 \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( (value && value.isColor) ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular : { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\n\t\t\t\t{\n\t\t\t\t\temissive : { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity : { value: 1 }, // temporary\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\n\t\t\t\t{\n\t\t\t\t\tscale : { value: 1 },\n\t\t\t\t\tdashSize : { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: {\n\n\t\t\t\topacity : { value: 1.0 }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\n\t\t\t\tlightPos: { value: new Vector3() }\n\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\n\t\t\tShaderLib.standard.uniforms,\n\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t point.y < this.min.y || point.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyProjection( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( (fog && fog.isFog) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( (fog && fog.isFogExp2) ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: MaterialIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( (currentValue && currentValue.isColor) ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( (currentValue && currentValue.isVector3) && (newValue && newValue.isVector3) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( (this.color && this.color.isColor) ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();\n\t\t\tif ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\n\t\t\tif ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.bumpMap && this.bumpMap.isTexture) ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( (this.normalMap && this.normalMap.isTexture) ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( (this.displacementMap && this.displacementMap.isTexture) ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( (this.envMap && this.envMap.isTexture) ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\tvar count$1 = 0;\n\tfunction MaterialIdCount() { return count$1++; }\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tthis.makeEmpty();\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tvar array, offset, stride;\n\n\t\t\t\t\t\t\t\tif ( (attribute && attribute.isInterleavedBufferAttribute) ) {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.data.array;\n\t\t\t\t\t\t\t\t\toffset = attribute.offset;\n\t\t\t\t\t\t\t\t\tstride = attribute.data.stride;\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tarray = attribute.array;\n\t\t\t\t\t\t\t\t\toffset = 0;\n\t\t\t\t\t\t\t\t\tstride = 3;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfor ( var i = offset, il = array.length; i < il; i += stride ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromArray( array, i );\n\t\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tif ( point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\t\t point.y < this.min.y || point.y > this.max.y ||\n\t\t\t\t\t point.z < this.min.z || point.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\tif ( ( this.min.x <= box.min.x ) && ( box.max.x <= this.max.x ) &&\n\t\t\t\t ( this.min.y <= box.min.y ) && ( box.max.y <= this.max.y ) &&\n\t\t\t\t ( this.min.z <= box.min.z ) && ( box.max.z <= this.max.z ) ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\n\t\t\tif ( box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\t\t box.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\t\t box.max.z < this.min.z || box.min.z > this.max.z ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// 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.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box = new Box3();\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToVector3Array: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToVector3Array( array, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = array.length;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i += 3, j += 3 ) {\n\n\t\t\t\t\tv1.fromArray( array, j );\n\t\t\t\t\tv1.applyMatrix3( this );\n\t\t\t\t\tv1.toArray( array, j );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyToBuffer: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBuffer( buffer, offset, length ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tif ( offset === undefined ) offset = 0;\n\t\t\t\tif ( length === undefined ) length = buffer.length / buffer.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = offset; i < length; i ++, j ++ ) {\n\n\t\t\t\t\tv1.x = buffer.getX( j );\n\t\t\t\t\tv1.y = buffer.getY( j );\n\t\t\t\t\tv1.z = buffer.getZ( j );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tbuffer.setXYZ( j, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn buffer;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( (matrix && matrix.isMatrix4) ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset is deprecated \" +\n\t\t\t\t\t\"- just use .toArray instead.\" );\n\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.clearColor( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( (light && light.isPointLight) ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( (shadow && shadow.isSpotLightShadow) ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( (material && material.isMultiMaterial) ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: Object3DIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function(){}; \n\t\tthis.onAfterRender = function(){};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype, {\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( (object && object.isObject3D) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\tvar count$2 = 0;\n\tfunction Object3DIdCount() { return count$2++; }\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int16Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint16Array( array ), itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Int32Array( array ), itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Uint32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float32Array( array ), itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\treturn new BufferAttribute( new Float64Array( array ), itemSize );\n\n\t}\n\n\t// Deprecated\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [ [] ];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype, {\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( (geometry && geometry.isGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( (mesh && mesh.isMesh) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\tvar dupIndex = - 1;\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tdupIndex = n;\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [ [] ];\n\t\t\tthis.colors = [];\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( var i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( var i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( var k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tvar count$3 = 0;\n\tfunction GeometryIdCount() { return count$3++; }\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'DirectGeometry';\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tcomputeBoundingBox: Geometry.prototype.computeBoundingBox,\n\t\tcomputeBoundingSphere: Geometry.prototype.computeBoundingSphere,\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tconsole.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );\n\n\t\t},\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype, {\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tthis.index = index;\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( (attribute && attribute.isBufferAttribute) === false && (attribute && attribute.isInterleavedBufferAttribute) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToVector3Array( position.array );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToVector3Array( normal.array );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isPoints) || (object && object.isLine) ) {\n\n\t\t\t\tvar positions = new Float32Attribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32Attribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32Attribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( (object && object.isMesh) ) {\n\n\t\t\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( (object && object.isMesh) ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32Attribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32Attribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32Attribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar positions = this.attributes.position.array;\n\n\t\t\tif ( positions !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromArray( positions );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar positions = this.attributes.position;\n\n\t\t\t\tif ( positions ) {\n\n\t\t\t\t\tvar array = positions.array;\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromArray( array );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i += 3 ) {\n\n\t\t\t\t\t\tvector.fromArray( array, i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC,\n\n\t\t\t\tpA = new Vector3(),\n\t\t\t\tpB = new Vector3(),\n\t\t\t\tpC = new Vector3(),\n\n\t\t\t\tcb = new Vector3(),\n\t\t\t\tab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( (geometry && geometry.isBufferGeometry) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t} );\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) {\n\n\t\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\t\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\t\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar uvs, intersection;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( attributes.uv !== undefined ) {\n\n\t\t\t\t\t\tuvs = attributes.uv.array;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = indices[ i ];\n\t\t\t\t\t\t\tb = indices[ i + 1 ];\n\t\t\t\t\t\t\tc = indices[ i + 2 ];\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length; i < l; i += 9 ) {\n\n\t\t\t\t\t\t\ta = i / 3;\n\t\t\t\t\t\t\tb = a + 1;\n\t\t\t\t\t\t\tc = a + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = (material && material.isMultiMaterial);\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );\n\t\tvar indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\t\tvar numberOfVertices = 0;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount( w, h, d ) {\n\n\t\t\tvar vertices = 0;\n\n\t\t\t// calculate the amount of vertices for each side (plane)\n\t\t\tvertices += (w + 1) * (h + 1) * 2; // xy\n\t\t\tvertices += (w + 1) * (d + 1) * 2; // xz\n\t\t\tvertices += (d + 1) * (h + 1) * 2; // zy\n\n\t\t\treturn vertices;\n\n\t\t}\n\n\t\tfunction calculateIndexCount( w, h, d ) {\n\n\t\t\tvar index = 0;\n\n\t\t\t// calculate the amount of squares for each side\n\t\t\tindex += w * h * 2; // xy\n\t\t\tindex += w * d * 2; // xz\n\t\t\tindex += d * h * 2; // zy\n\n\t\t\treturn index * 6; // two triangles per square => six vertices per square\n\n\t\t}\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth\t= width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\t\t\t\t\tvertices[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// set values to correct vector component\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\t\t\t\t\tnormals[ vertexBufferOffset ] = vector.x;\n\t\t\t\t\tnormals[ vertexBufferOffset + 1 ] = vector.y;\n\t\t\t\t\tnormals[ vertexBufferOffset + 2 ] = vector.z;\n\n\t\t\t\t\t// uvs\n\t\t\t\t\tuvs[ uvBufferOffset ] = ix / gridX;\n\t\t\t\t\tuvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\t\tuvBufferOffset += 2;\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\t// indices\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t\t// update offsets and counters\n\t\t\t\t\tindexBufferOffset += 6;\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar vertices = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar normals = new Float32Array( gridX1 * gridY1 * 3 );\n\t\tvar uvs = new Float32Array( gridX1 * gridY1 * 2 );\n\n\t\tvar offset = 0;\n\t\tvar offset2 = 0;\n\n\t\tfor ( var iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( var ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices[ offset ] = x;\n\t\t\t\tvertices[ offset + 1 ] = - y;\n\n\t\t\t\tnormals[ offset + 2 ] = 1;\n\n\t\t\t\tuvs[ offset2 ] = ix / gridX;\n\t\t\t\tuvs[ offset2 + 1 ] = 1 - ( iy / gridY );\n\n\t\t\t\toffset += 3;\n\t\t\t\toffset2 += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\toffset = 0;\n\n\t\tvar indices = new ( ( vertices.length / 3 ) > 65535 ? Uint32Array : Uint16Array )( gridX * gridY * 6 );\n\n\t\tfor ( var iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( var ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices[ offset ] = a;\n\t\t\t\tindices[ offset + 1 ] = b;\n\t\t\t\tindices[ offset + 2 ] = d;\n\n\t\t\t\tindices[ offset + 3 ] = b;\n\t\t\t\tindices[ offset + 4 ] = c;\n\t\t\t\tindices[ offset + 5 ] = d;\n\n\t\t\t\toffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makeFrustum(\n\t\t\t\t\tleft, left + width, top - height, top, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( (position && position.isInterleavedBufferAttribute) ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( 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\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( (map && map.isTexture) ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( (map && map.isWebGLRenderTarget) ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\t\t\tvar position = attributes.position;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar edges = {};\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar TypeArray = position.count > 65535 ? Uint32Array : Uint16Array;\n\t\t\tvar attribute = new BufferAttribute( new TypeArray( indices ), 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) return true;\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) return true;\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( (renderTarget && renderTarget.isWebGLRenderTargetCube) ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = (texture && texture.isCompressedTexture);\n\t\t\t\t\tvar isDataTexture = (texture.image[ 0 ] && texture.image[ 0 ].isDataTexture);\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( (texture && texture.isDepthTexture) ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( (texture && texture.isDataTexture) ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( (texture && texture.isCompressedTexture) ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( (renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture) ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( (renderTarget && renderTarget.isWebGLRenderTargetCube) );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a ) {\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tclearColor( 0, 0, 0, 1 );\n\t\t\tclearDepth( 1 );\n\t\t\tclearStencil( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tgl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction clearColor( r, g, b, a ) {\n\n\t\t\tcolorBuffer.setClear( r, g, b, a );\n\n\t\t}\n\n\t\tfunction clearDepth( depth ) {\n\n\t\t\tdepthBuffer.setClear( depth );\n\n\t\t}\n\n\t\tfunction clearStencil( stencil ) {\n\n\t\t\tstencilBuffer.setClear( stencil );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tclearColor: clearColor,\n\t\t\tclearDepth: clearDepth,\n\t\t\tclearStencil: clearStencil,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t// internal state cache\n\n\t\t_currentProgram = null,\n\t\t_currentRenderTarget = null,\n\t\t_currentFramebuffer = null,\n\t\t_currentMaterialId = - 1,\n\t\t_currentGeometryProgram = '',\n\t\t_currentCamera = null,\n\n\t\t_currentScissor = new Vector4(),\n\t\t_currentScissorTest = null,\n\n\t\t_currentViewport = new Vector4(),\n\n\t\t//\n\n\t\t_usedTextureUnits = 0,\n\n\t\t//\n\n\t\t_clearColor = new Color( 0x000000 ),\n\t\t_clearAlpha = 0,\n\n\t\t_width = _canvas.width,\n\t\t_height = _canvas.height,\n\n\t\t_pixelRatio = 1,\n\n\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t_scissorTest = false,\n\n\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t// frustum\n\n\t\t_frustum = new Frustum(),\n\n\t\t// clipping\n\n\t\t_clipping = new WebGLClipping(),\n\t\t_clippingEnabled = false,\n\t\t_localClippingEnabled = false,\n\n\t\t_sphere = new Sphere(),\n\n\t\t// camera matrices cache\n\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_vector3 = new Vector3(),\n\n\t\t// light arrays cache\n\n\t\t_lights = {\n\n\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\tshadows: []\n\n\t\t},\n\n\t\t// info\n\n\t\t_infoRender = {\n\n\t\t\tcalls: 0,\n\t\t\tvertices: 0,\n\t\t\tfaces: 0,\n\t\t\tpoints: 0\n\n\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\t\tvar backgroundCamera2 = new PerspectiveCamera();\n\t\tvar backgroundPlaneMesh = new Mesh(\n\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t);\n\t\tvar backgroundBoxShader = ShaderLib[ 'cube' ];\n\t\tvar backgroundBoxMesh = new Mesh(\n\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\tnew ShaderMaterial( {\n\t\t\t\tuniforms: backgroundBoxShader.uniforms,\n\t\t\t\tvertexShader: backgroundBoxShader.vertexShader,\n\t\t\t\tfragmentShader: backgroundBoxShader.fragmentShader,\n\t\t\t\tside: BackSide,\n\t\t\t\tdepthTest: false,\n\t\t\t\tdepthWrite: false,\n\t\t\t\tfog: false\n\t\t\t} )\n\t\t);\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction glClearColor( r, g, b, a ) {\n\n\t\t\tif ( _premultipliedAlpha === true ) {\n\n\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t}\n\n\t\t\tstate.clearColor( r, g, b, a );\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t ! material.isMeshStandardMaterial &&\n\t\t\t\t material.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar type = _gl.FLOAT;\n\t\t\t\t\t\tvar array = geometryAttribute.array;\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\n\t\t\t\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.FLOAT;\n\n\t\t\t\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.SHORT;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.INT;\n\n\t\t\t\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.BYTE;\n\n\t\t\t\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\t\t\t\ttype = _gl.UNSIGNED_BYTE;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\t\t\t\t\t\tvar buffer = objects.getAttributeBuffer( geometryAttribute );\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tglClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tglClearColor( background.r, background.g, background.b, 1 );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tbackgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyProjection( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t ! material.isRawShaderMaterial ||\n\t\t\t material.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes || \n\t \t\t\t\t materialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isShaderMaterial ||\n\t\t\t\t material.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t material.isMeshLambertMaterial ||\n\t\t\t\t material.isMeshPhongMaterial ||\n\t\t\t\t material.isMeshStandardMaterial ||\n\t\t\t\t material.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\tm_uniforms.opacity.value = material.opacity;\n\n\t\t\t\t}\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\tr = 0, g = 0, b = 0,\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\tdistance,\n\t\t\tshadowMap,\n\n\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\t p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone( skin ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t\tthis.skin = skin;\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.skin = source.skin;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone( this );\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( (this.geometry && this.geometry.isGeometry) ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( (geometry && geometry.isGeometry) ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.type = type !== undefined ? type : UnsignedShortType;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tif ( (geometry && geometry.isGeometry) ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar numEdges = 0;\n\n\t\t\t// allocate maximal size\n\t\t\tvar edges = new Uint32Array( 6 * faces.length );\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\tvar vertex = vertices[ edges [ 2 * i + j ] ];\n\n\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\tcoords[ index + 0 ] = vertex.x;\n\t\t\t\t\tcoords[ index + 1 ] = vertex.y;\n\t\t\t\t\tcoords[ index + 2 ] = vertex.z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t} else if ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// Indexed BufferGeometry\n\n\t\t\t\tvar indices = geometry.index.array;\n\t\t\t\tvar vertices = geometry.attributes.position;\n\t\t\t\tvar groups = geometry.groups;\n\t\t\t\tvar numEdges = 0;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.length );\n\n\t\t\t\t}\n\n\t\t\t\t// allocate maximal size\n\t\t\t\tvar edges = new Uint32Array( 2 * indices.length );\n\n\t\t\t\tfor ( var o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tvar group = groups[ o ];\n\n\t\t\t\t\tvar start = group.start;\n\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices[ i + j ];\n\t\t\t\t\t\t\tedge[ 1 ] = indices[ i + ( j + 1 ) % 3 ];\n\t\t\t\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\t\t\t\tvar key = edge.toString();\n\n\t\t\t\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges ] = edge[ 0 ];\n\t\t\t\t\t\t\t\tedges[ 2 * numEdges + 1 ] = edge[ 1 ];\n\t\t\t\t\t\t\t\thash[ key ] = true;\n\t\t\t\t\t\t\t\tnumEdges ++;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numEdges; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 2; j ++ ) {\n\n\t\t\t\t\t\tvar index = 6 * i + 3 * j;\n\t\t\t\t\t\tvar index2 = edges[ 2 * i + j ];\n\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices.getX( index2 );\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices.getY( index2 );\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices.getZ( index2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tvar vertices = geometry.attributes.position.array;\n\t\t\t\tvar numEdges = vertices.length / 3;\n\t\t\t\tvar numTris = numEdges / 3;\n\n\t\t\t\tvar coords = new Float32Array( numEdges * 2 * 3 );\n\n\t\t\t\tfor ( var i = 0, l = numTris; i < l; i ++ ) {\n\n\t\t\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\tvar index = 18 * i + 6 * j;\n\n\t\t\t\t\t\tvar index1 = 9 * i + 3 * j;\n\t\t\t\t\t\tcoords[ index + 0 ] = vertices[ index1 ];\n\t\t\t\t\t\tcoords[ index + 1 ] = vertices[ index1 + 1 ];\n\t\t\t\t\t\tcoords[ index + 2 ] = vertices[ index1 + 2 ];\n\n\t\t\t\t\t\tvar index2 = 9 * i + 3 * ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tcoords[ index + 3 ] = vertices[ index2 ];\n\t\t\t\t\t\tcoords[ index + 4 ] = vertices[ index2 + 1 ];\n\t\t\t\t\t\tcoords[ index + 5 ] = vertices[ index2 + 2 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.addAttribute( 'position', new BufferAttribute( coords, 3 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// generate vertices and uvs\n\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j, p;\n\t\tvar u, v;\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tv = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tu = j / slices;\n\n\t\t\t\tp = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tvar indices = [];\n\t\tvar a, b, c, d;\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\ta = i * sliceCount + j;\n\t\t\t\tb = i * sliceCount + j + 1;\n\t\t\t\tc = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\td = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', Float32Attribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0 ; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols ; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius,detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t *\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( ( indices.length > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', Float32Attribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', Float32Attribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', Float32Attribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar i, j, index = 0, indexOffset = 0;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\tuv.y = j / radialSegments;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// used to calculate buffer length\n\t\tvar vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );\n\t\tvar indexCount = radialSegments * tubularSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );\n\t\tvar vertices = new Float32Array( vertexCount * 3 );\n\t\tvar normals = new Float32Array( vertexCount * 3 );\n\t\tvar uvs = new Float32Array( vertexCount * 2 );\n\n\t\t// offset variables\n\t\tvar vertexBufferOffset = 0;\n\t\tvar uvBufferOffset = 0;\n\t\tvar indexBufferOffset = 0;\n\n\t\t// helper variables\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices[ vertexBufferOffset ] = vertex.x;\n\t\t\t\tvertices[ vertexBufferOffset + 1 ] = vertex.y;\n\t\t\t\tvertices[ vertexBufferOffset + 2 ] = vertex.z;\n\n\t\t\t\t// this vector is used to calculate the normal\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\n\t\t\t\t// normal\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals[ vertexBufferOffset ] = normal.x;\n\t\t\t\tnormals[ vertexBufferOffset + 1 ] = normal.y;\n\t\t\t\tnormals[ vertexBufferOffset + 2 ] = normal.z;\n\n\t\t\t\t// uv\n\t\t\t\tuvs[ uvBufferOffset ] = i / tubularSegments;\n\t\t\t\tuvs[ uvBufferOffset + 1 ] = j / radialSegments;\n\n\t\t\t\t// update offsets\n\t\t\t\tvertexBufferOffset += 3;\n\t\t\t\tuvBufferOffset += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// face one\n\t\t\t\tindices[ indexBufferOffset ] = a;\n\t\t\t\tindices[ indexBufferOffset + 1 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 2 ] = d;\n\n\t\t\t\t// face two\n\t\t\t\tindices[ indexBufferOffset + 3 ] = b;\n\t\t\t\tindices[ indexBufferOffset + 4 ] = c;\n\t\t\t\tindices[ indexBufferOffset + 5 ] = d;\n\n\t\t\t\t// update offset\n\t\t\t\tindexBufferOffset += 6;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\t\tthis.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// 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.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t},\n\n\t\t// Bezier Curves formulas obtained from\n\t\t// http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n\t\t// Quad Bezier Functions\n\n\t\tb2: ( function () {\n\n\t\t\tfunction b2p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p1( t, p ) {\n\n\t\t\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b2p2( t, p ) {\n\n\t\t\t\treturn t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b2( t, p0, p1, p2 ) {\n\n\t\t\t\treturn b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\t// Cubic Bezier Functions\n\n\t\tb3: ( function () {\n\n\t\t\tfunction b3p0( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn k * k * k * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p1( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * k * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p2( t, p ) {\n\n\t\t\t\tvar k = 1 - t;\n\t\t\t\treturn 3 * k * t * t * p;\n\n\t\t\t}\n\n\t\t\tfunction b3p3( t, p ) {\n\n\t\t\t\treturn t * t * t * p;\n\n\t\t\t}\n\n\t\t\treturn function b3( t, p0, p1, p2, p3 ) {\n\n\t\t\t\treturn b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( (font && font.isFont) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * based on THREE.SphereGeometry\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );\n\n\t\tvar positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\tvar index = 0, vertices = [], normal = new Vector3();\n\n\t\tfor ( var y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = y / heightSegments;\n\n\t\t\tfor ( var x = 0; x <= widthSegments; x ++ ) {\n\n\t\t\t\tvar u = x / widthSegments;\n\n\t\t\t\tvar px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvar py = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvar pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tnormal.set( px, py, pz ).normalize();\n\n\t\t\t\tpositions.setXYZ( index, px, py, pz );\n\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\tverticesRow.push( index );\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\tvertices.push( verticesRow );\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var y = 0; y < heightSegments; y ++ ) {\n\n\t\t\tfor ( var x = 0; x < widthSegments; x ++ ) {\n\n\t\t\t\tvar v1 = vertices[ y ][ x + 1 ];\n\t\t\t\tvar v2 = vertices[ y ][ x ];\n\t\t\t\tvar v3 = vertices[ y + 1 ][ x ];\n\t\t\t\tvar v4 = vertices[ y + 1 ][ x + 1 ];\n\n\t\t\t\tif ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );\n\t\t\t\tif ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );\n\t\tthis.addAttribute( 'position', positions );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 );\n\t\tvar indexCount = thetaSegments * phiSegments * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// some helper variables\n\t\tvar index = 0, indexOffset = 0, segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\t// values are generate from the inside of the ring to the outside\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, 0, 1 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex++;\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\t // points - to create a closed torus, one must use a set of points\n\t // like so: [ a, b, c, d, a ], see first is the same as last.\n\t // segments - the number of circumference segments to create\n\t // phiStart - the starting radian\n\t // phiLength - the radian (0 to 2PI) range of the lathed section\n\t // 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// these are used to calculate buffer length\n\t\tvar vertexCount = ( segments + 1 ) * points.length;\n\t\tvar indexCount = segments * points.length * 2 * 3;\n\n\t\t// buffers\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\t\tvar index = 0, indexOffset = 0, base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\t// indices\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// face one\n\t\t\t\tindices.setX( indexOffset, a ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t\t// face two\n\t\t\t\tindices.setX( indexOffset, b ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, c ); indexOffset++;\n\t\t\t\tindices.setX( indexOffset, d ); indexOffset++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t} // next row\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t *\n\t * Creates a one-sided polygonal geometry from a path shape. Similar to\n\t * ExtrudeGeometry.\n\t *\n\t * parameters = {\n\t *\n\t *\tcurveSegments: , // number of points on the curves. NOT USED AT THE MOMENT.\n\t *\n\t *\tmaterial: // material index for front and back faces\n\t *\tuvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ShapeGeometry( shapes, options ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( Array.isArray( shapes ) === false ) shapes = [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * Add an array of shapes to THREE.ShapeGeometry.\n\t */\n\tShapeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tfor ( var i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tthis.addShape( shapes[ i ], options );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.\n\t */\n\tShapeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tif ( options === undefined ) options = {};\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar material = options.material;\n\t\tvar uvgen = options.UVGenerator === undefined ? ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;\n\n\t\t//\n\n\t\tvar i, l, hole;\n\n\t\tvar shapesOffset = this.vertices.length;\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe...\n\n\t\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\t\thole = holes[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( hole ) ) {\n\n\t\t\t\t\tholes[ i ] = hole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false;\n\n\t\t}\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t// Vertices\n\n\t\tfor ( i = 0, l = holes.length; i < l; i ++ ) {\n\n\t\t\thole = holes[ i ];\n\t\t\tvertices = vertices.concat( hole );\n\n\t\t}\n\n\t\t//\n\n\t\tvar vert, vlen = vertices.length;\n\t\tvar face, flen = faces.length;\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = vertices[ i ];\n\n\t\t\tthis.vertices.push( new Vector3( vert.x, vert.y, 0 ) );\n\n\t\t}\n\n\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\tface = faces[ i ];\n\n\t\t\tvar a = face[ 0 ] + shapesOffset;\n\t\t\tvar b = face[ 1 ] + shapesOffset;\n\t\t\tvar c = face[ 2 ] + shapesOffset;\n\n\t\t\tthis.faces.push( new Face3( a, b, c, null, null, material ) );\n\t\t\tthis.faceVertexUvs[ 0 ].push( uvgen.generateTopUV( this, a, b, c ) );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\n\t\tvar edge = [ 0, 0 ], hash = {};\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\tvar geometry2;\n\n\t\tif ( (geometry && geometry.isBufferGeometry) ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar vertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tvar key = edge.toString();\n\n\t\t\t\tif ( hash[ key ] === undefined ) {\n\n\t\t\t\t\thash[ key ] = { vert1: edge[ 0 ], vert2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\thash[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar coords = [];\n\n\t\tfor ( var key in hash ) {\n\n\t\t\tvar h = hash[ key ];\n\n\t\t\tif ( h.face2 === undefined || faces[ h.face1 ].normal.dot( faces[ h.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = vertices[ h.vert1 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t\tvertex = vertices[ h.vert2 ];\n\t\t\t\tcoords.push( vertex.x );\n\t\t\t\tcoords.push( vertex.y );\n\t\t\t\tcoords.push( vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.addAttribute( 'position', new BufferAttribute( new Float32Array( coords ), 3 ) );\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// used to calculate buffer length\n\n\t\tvar nbCap = 0;\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) nbCap ++;\n\t\t\tif ( radiusBottom > 0 ) nbCap ++;\n\n\t\t}\n\n\t\tvar vertexCount = calculateVertexCount();\n\t\tvar indexCount = calculateIndexCount();\n\n\t\t// buffers\n\n\t\tvar indices = new BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 );\n\t\tvar vertices = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );\n\t\tvar uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );\n\n\t\t// helper variables\n\n\t\tvar index = 0,\n\t\t indexOffset = 0,\n\t\t indexArray = [],\n\t\t halfHeight = height / 2;\n\n\t\t// group variables\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', vertices );\n\t\tthis.addAttribute( 'normal', normals );\n\t\tthis.addAttribute( 'uv', uvs );\n\n\t\t// helper functions\n\n\t\tfunction calculateVertexCount() {\n\n\t\t\tvar count = ( radialSegments + 1 ) * ( heightSegments + 1 );\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap );\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction calculateIndexCount() {\n\n\t\t\tvar count = radialSegments * heightSegments * 2 * 3;\n\n\t\t\tif ( openEnded === false ) {\n\n\t\t\t\tcount += radialSegments * nbCap * 3;\n\n\t\t\t}\n\n\t\t\treturn count;\n\n\t\t}\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.setXYZ( index, normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\t\t\t\t\tuvs.setXY( index, u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\t\t\t\t\tindexRow.push( index );\n\n\t\t\t\t\t// increase index\n\t\t\t\t\tindex ++;\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\tvar i1 = indexArray[ y ][ x ];\n\t\t\t\t\tvar i2 = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar i3 = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar i4 = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// face one\n\t\t\t\t\tindices.setX( indexOffset, i1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// face two\n\t\t\t\t\tindices.setX( indexOffset, i2 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i3 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i4 ); indexOffset ++;\n\n\t\t\t\t\t// update counters\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\t\t\t\tvertices.setXYZ( index, 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = 0.5;\n\t\t\t\tuv.y = 0.5;\n\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.setXYZ( index, vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\t\t\t\tnormals.setXYZ( index, 0, sign, 0 );\n\n\t\t\t\t// uv\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.setXY( index, uv.x, uv.y );\n\n\t\t\t\t// increase index\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\t\t\t\t\tindices.setX( indexOffset, i + 1 ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, i ); indexOffset ++;\n\t\t\t\t\tindices.setX( indexOffset, c ); indexOffset ++;\n\n\t\t\t\t}\n\n\t\t\t\t// update counters\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tvar vertices = segments + 2;\n\n\t\tvar positions = new Float32Array( vertices * 3 );\n\t\tvar normals = new Float32Array( vertices * 3 );\n\t\tvar uvs = new Float32Array( vertices * 2 );\n\n\t\t// center data is already zero, but need to set a few extras\n\t\tnormals[ 2 ] = 1.0;\n\t\tuvs[ 0 ] = 0.5;\n\t\tuvs[ 1 ] = 0.5;\n\n\t\tfor ( var s = 0, i = 3, ii = 2 ; s <= segments; s ++, i += 3, ii += 2 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\tpositions[ i ] = radius * Math.cos( segment );\n\t\t\tpositions[ i + 1 ] = radius * Math.sin( segment );\n\n\t\t\tnormals[ i + 2 ] = 1; // normal z\n\n\t\t\tuvs[ ii ] = ( positions[ i ] / radius + 1 ) / 2;\n\t\t\tuvs[ ii + 1 ] = ( positions[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t}\n\n\t\tvar indices = [];\n\n\t\tfor ( var i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\tthis.setIndex( new BufferAttribute( new Uint16Array( indices ), 1 ) );\n\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );\n\n\t\tthis.boundingSphere = new Sphere( new Vector3(), radius );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry,\n\t\tBoxGeometry: BoxGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib[ \"lights\" ],\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = materials instanceof Array ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction XHRLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( XHRLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[1];\n\t\t\t\tvar isBase64 = !!dataUriRegexResult[2];\n\t\t\t\tvar data = dataUriRegexResult[3];\n\n\t\t\t\tdata = window.decodeURIComponent(data);\n\n\t\t\t\tif( isBase64 ) {\n\t\t\t\t\tdata = window.atob(data);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { \"type\" : mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function() {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0);\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tvar DataTextureLoader = BinaryTextureLoader;\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( BinaryTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\t\t\timage.onload = function () {\n\n\t\t\t\timage.onload = null;\n\n\t\t\t\tURL.revokeObjectURL( image.src );\n\n\t\t\t\tif ( onLoad ) onLoad( image );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t};\n\t\t\timage.onerror = onError;\n\n\t\t\tif ( url.indexOf( 'data:' ) === 0 ) {\n\n\t\t\t\timage.src = url;\n\n\t\t\t} else {\n\n\t\t\t\tvar loader = new XHRLoader();\n\t\t\t\tloader.setPath( this.path );\n\t\t\t\tloader.setResponseType( 'blob' );\n\t\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\t\tloader.load( url, function ( blob ) {\n\n\t\t\t\t\timage.src = URL.createObjectURL( blob );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( light ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true,\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function() {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function() {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function( timeOffset ) {\n\n\t\t\tif( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function( timeScale ) {\n\n\t\t\tif( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== -1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to , 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function() {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function() {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number',\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max(\n\t\t\t\t\t\tduration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0;\n\t\t\t\t\t\t\t\tm !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack(\n\t\t\t\t\t\t\t\t'.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader ( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tscope.parse( JSON.parse( text ), onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.SplineCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( ! divisions ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = 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\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\t// TODO: Transformation for Curves?\n\n\t/**************************************************************\n\t *\t3D Curves\n\t **************************************************************/\n\n\t// A Factory method for creating new curve subclasses\n\n\tCurve.create = function ( constructor, getPointFunc ) {\n\n\t\tconstructor.prototype = Object.create( Curve.prototype );\n\t\tconstructor.prototype.constructor = constructor;\n\t\tconstructor.prototype.getPoint = getPointFunc;\n\n\t\treturn constructor;\n\n\t};\n\n\t/**************************************************************\n\t *\tLine\n\t **************************************************************/\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**************************************************************\n\t *\tEllipse curve\n\t **************************************************************/\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar CurveUtils = {\n\n\t\ttangentQuadraticBezier: function ( t, p0, p1, p2 ) {\n\n\t\t\treturn 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );\n\n\t\t},\n\n\t\t// Puay Bing, thanks for helping with this derivative!\n\n\t\ttangentCubicBezier: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\treturn - 3 * p0 * ( 1 - t ) * ( 1 - t ) +\n\t\t\t\t3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +\n\t\t\t\t6 * t * p2 * ( 1 - t ) - 3 * t * t * p2 +\n\t\t\t\t3 * t * t * p3;\n\n\t\t},\n\n\t\ttangentSpline: function ( t, p0, p1, p2, p3 ) {\n\n\t\t\t// To check if my formulas are correct\n\n\t\t\tvar h00 = 6 * t * t - 6 * t; \t// derived from 2t^3 − 3t^2 + 1\n\t\t\tvar h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t\n\t\t\tvar h01 = - 6 * t * t + 6 * t; \t// − 2t3 + 3t2\n\t\t\tvar h11 = 3 * t * t - 2 * t;\t// t3 − t2\n\n\t\t\treturn h00 + h10 + h01 + h11;\n\n\t\t},\n\n\t\t// Catmull-Rom\n\n\t\tinterpolate: function( p0, p1, p2, p3, t ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t * t2;\n\t\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t};\n\n\t/**************************************************************\n\t *\tSpline curve\n\t **************************************************************/\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\treturn new Vector2(\n\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight )\n\t\t);\n\n\t};\n\n\t/**************************************************************\n\t *\tCubic Bezier curve\n\t **************************************************************/\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b3 = ShapeUtils.b3;\n\n\t\treturn new Vector2(\n\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t);\n\n\t};\n\n\tCubicBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentCubicBezier = CurveUtils.tangentCubicBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\ttangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )\n\t\t).normalize();\n\n\t};\n\n\t/**************************************************************\n\t *\tQuadratic Bezier curve\n\t **************************************************************/\n\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar b2 = ShapeUtils.b2;\n\n\t\treturn new Vector2(\n\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t);\n\n\t};\n\n\n\tQuadraticBezierCurve.prototype.getTangent = function( t ) {\n\n\t\tvar tangentQuadraticBezier = CurveUtils.tangentQuadraticBezier;\n\n\t\treturn new Vector2(\n\t\t\ttangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\ttangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )\n\t\t).normalize();\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t *\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\n\t// minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\tfunction ShapePath() {\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\t}\n\n\tShapePath.prototype = {\n\t\tmoveTo: function ( x, y ) {\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push(this.currentPath);\n\t\t\tthis.currentPath.moveTo( x, y );\n\t\t},\n\t\tlineTo: function ( x, y ) {\n\t\t\tthis.currentPath.lineTo( x, y );\n\t\t},\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\t\t},\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\t\t},\n\t\tsplineThru: function ( pts ) {\n\t\t\tthis.currentPath.splineThru( pts );\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar offset = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar ret = createPath( chars[ i ], scale, offset );\n\t\t\t\t\toffset += ret.offset;\n\n\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offset ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [], b2 = ShapeUtils.b2, b3 = ShapeUtils.b3;\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb2( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tb2( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offset;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tb3( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tb3( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offset: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tfunction getAudioContext() {\n\n\t\tif ( context === undefined ) {\n\n\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn context;\n\n\t}\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new XHRLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = getAudioContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = getAudioContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\t\tthis.source = this.context.createBufferSource();\n\t\tthis.source.onended = this.onEnded.bind( this );\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.source.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.source.buffer;\n\t\t\tsource.loop = this.source.loop;\n\t\t\tsource.onended = this.source.onended;\n\t\t\tsource.start( 0, this.startTime );\n\t\t\tsource.playbackRate.value = this.playbackRate;\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.value = this.playbackRate;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.source.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.loop = value;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\t\t\tmixFunction = this._slerp;\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\n\t\t\t\tbufferType = Array,\t\tmixFunction = this._select;\t\tbreak;\n\n\t\t\tdefault:\t\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( (root && root.isAnimationObjectGroup) ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:\\w+[\\/:])*)(\\w+)?(?:\\.(\\w+)(?:\\[(.+)\\])?)?\\.(\\w+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tvar knownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis.loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant(),\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype, {\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function() {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function() {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function() {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function() {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Spline from Tween.js, slightly optimized (and trashed)\n\t * http://sole.github.com/tween.js/examples/05_spline.html\n\t *\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Spline( points ) {\n\n\t\tthis.points = points;\n\n\t\tvar c = [], v3 = { x: 0, y: 0, z: 0 },\n\t\tpoint, intPoint, weight, w2, w3,\n\t\tpa, pb, pc, pd;\n\n\t\tthis.initFromArray = function ( a ) {\n\n\t\t\tthis.points = [];\n\n\t\t\tfor ( var i = 0; i < a.length; i ++ ) {\n\n\t\t\t\tthis.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getPoint = function ( k ) {\n\n\t\t\tpoint = ( this.points.length - 1 ) * k;\n\t\t\tintPoint = Math.floor( point );\n\t\t\tweight = point - intPoint;\n\n\t\t\tc[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;\n\t\t\tc[ 1 ] = intPoint;\n\t\t\tc[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;\n\t\t\tc[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;\n\n\t\t\tpa = this.points[ c[ 0 ] ];\n\t\t\tpb = this.points[ c[ 1 ] ];\n\t\t\tpc = this.points[ c[ 2 ] ];\n\t\t\tpd = this.points[ c[ 3 ] ];\n\n\t\t\tw2 = weight * weight;\n\t\t\tw3 = weight * w2;\n\n\t\t\tv3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );\n\t\t\tv3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );\n\t\t\tv3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );\n\n\t\t\treturn v3;\n\n\t\t};\n\n\t\tthis.getControlPointsArray = function () {\n\n\t\t\tvar i, p, l = this.points.length,\n\t\t\t\tcoords = [];\n\n\t\t\tfor ( i = 0; i < l; i ++ ) {\n\n\t\t\t\tp = this.points[ i ];\n\t\t\t\tcoords[ i ] = [ p.x, p.y, p.z ];\n\n\t\t\t}\n\n\t\t\treturn coords;\n\n\t\t};\n\n\t\t// approximate length by summing linear segments\n\n\t\tthis.getLength = function ( nSubDivisions ) {\n\n\t\t\tvar i, index, nSamples, position,\n\t\t\t\tpoint = 0, intPoint = 0, oldIntPoint = 0,\n\t\t\t\toldPosition = new Vector3(),\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tchunkLengths = [],\n\t\t\t\ttotalLength = 0;\n\n\t\t\t// first point has 0 length\n\n\t\t\tchunkLengths[ 0 ] = 0;\n\n\t\t\tif ( ! nSubDivisions ) nSubDivisions = 100;\n\n\t\t\tnSamples = this.points.length * nSubDivisions;\n\n\t\t\toldPosition.copy( this.points[ 0 ] );\n\n\t\t\tfor ( i = 1; i < nSamples; i ++ ) {\n\n\t\t\t\tindex = i / nSamples;\n\n\t\t\t\tposition = this.getPoint( index );\n\t\t\t\ttmpVec.copy( position );\n\n\t\t\t\ttotalLength += tmpVec.distanceTo( oldPosition );\n\n\t\t\t\toldPosition.copy( position );\n\n\t\t\t\tpoint = ( this.points.length - 1 ) * index;\n\t\t\t\tintPoint = Math.floor( point );\n\n\t\t\t\tif ( intPoint !== oldIntPoint ) {\n\n\t\t\t\t\tchunkLengths[ intPoint ] = totalLength;\n\t\t\t\t\toldIntPoint = intPoint;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// last point ends with total length\n\n\t\t\tchunkLengths[ chunkLengths.length ] = totalLength;\n\n\t\t\treturn { chunks: chunkLengths, total: totalLength };\n\n\t\t};\n\n\t\tthis.reparametrizeByArcLength = function ( samplingCoef ) {\n\n\t\t\tvar i, j,\n\t\t\t\tindex, indexCurrent, indexNext,\n\t\t\t\trealDistance,\n\t\t\t\tsampling, position,\n\t\t\t\tnewpoints = [],\n\t\t\t\ttmpVec = new Vector3(),\n\t\t\t\tsl = this.getLength();\n\n\t\t\tnewpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );\n\n\t\t\tfor ( i = 1; i < this.points.length; i ++ ) {\n\n\t\t\t\t//tmpVec.copy( this.points[ i - 1 ] );\n\t\t\t\t//linearDistance = tmpVec.distanceTo( this.points[ i ] );\n\n\t\t\t\trealDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];\n\n\t\t\t\tsampling = Math.ceil( samplingCoef * realDistance / sl.total );\n\n\t\t\t\tindexCurrent = ( i - 1 ) / ( this.points.length - 1 );\n\t\t\t\tindexNext = i / ( this.points.length - 1 );\n\n\t\t\t\tfor ( j = 1; j < sampling - 1; j ++ ) {\n\n\t\t\t\t\tindex = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );\n\n\t\t\t\t\tposition = this.getPoint( index );\n\t\t\t\t\tnewpoints.push( tmpVec.copy( position ).clone() );\n\n\t\t\t\t}\n\n\t\t\t\tnewpoints.push( tmpVec.copy( this.points[ i ] ).clone() );\n\n\t\t\t}\n\n\t\t\tthis.points = newpoints;\n\n\t\t};\n\n\t\t// Catmull-Rom\n\n\t\tfunction interpolate( p0, p1, p2, p3, t, t2, t3 ) {\n\n\t\t\tvar v0 = ( p2 - p0 ) * 0.5,\n\t\t\t\tv1 = ( p3 - p1 ) * 0.5;\n\n\t\t\treturn ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new Geometry();\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\t\tgeometry.colors.push( new Color( 0, 0, 1 ) );\n\t\t\t\tgeometry.colors.push( new Color( 0, 1, 0 ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.dynamic = true;\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( (object && object.isBone) ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar geometry = this.geometry;\n\n\t\tvar matrixWorldInv = new Matrix4().getInverse( this.root.matrixWorld );\n\n\t\tvar boneMatrix = new Matrix4();\n\n\t\tvar j = 0;\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( (bone.parent && bone.parent.isBone) ) {\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\tgeometry.vertices[ j ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\tgeometry.vertices[ j + 1 ].setFromMatrixPosition( boneMatrix );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.verticesNeedUpdate = true;\n\n\t\tgeometry.computeBoundingSphere();\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction HemisphereLightHelper( light, sphereSize ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.colors = [ new Color(), new Color() ];\n\n\t\tvar geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tgeometry.rotateX( - Math.PI / 2 );\n\n\t\tfor ( var i = 0, il = 8; i < il; i ++ ) {\n\n\t\t\tgeometry.faces[ i ].color = this.colors[ i < 4 ? 0 : 1 ];\n\n\t\t}\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: FaceColors, wireframe: true } );\n\n\t\tthis.lightSphere = new Mesh( geometry, material );\n\t\tthis.add( this.lightSphere );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.lightSphere.geometry.dispose();\n\t\tthis.lightSphere.material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tthis.colors[ 0 ].copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tthis.colors[ 1 ].copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tthis.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\t\t\tthis.lightSphere.geometry.colorsNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tdivisions = divisions || 1;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = ( size * 2 ) / divisions;\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - size; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - size, 0, k, size, 0, k );\n\t\t\tvertices.push( k, 0, - size, k, 0, size );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32Attribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( (objGeometry && objGeometry.isGeometry) ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32Attribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new Geometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar hexFrustum = 0xffaa00;\n\t\tvar hexCone = 0xff0000;\n\t\tvar hexUp = 0x00aaff;\n\t\tvar hexTarget = 0xffffff;\n\t\tvar hexCross = 0x333333;\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", hexFrustum );\n\t\taddLine( \"n2\", \"n4\", hexFrustum );\n\t\taddLine( \"n4\", \"n3\", hexFrustum );\n\t\taddLine( \"n3\", \"n1\", hexFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", hexFrustum );\n\t\taddLine( \"f2\", \"f4\", hexFrustum );\n\t\taddLine( \"f4\", \"f3\", hexFrustum );\n\t\taddLine( \"f3\", \"f1\", hexFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", hexFrustum );\n\t\taddLine( \"n2\", \"f2\", hexFrustum );\n\t\taddLine( \"n3\", \"f3\", hexFrustum );\n\t\taddLine( \"n4\", \"f4\", hexFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", hexCone );\n\t\taddLine( \"p\", \"n2\", hexCone );\n\t\taddLine( \"p\", \"n3\", hexCone );\n\t\taddLine( \"p\", \"n4\", hexCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", hexUp );\n\t\taddLine( \"u2\", \"u3\", hexUp );\n\t\taddLine( \"u3\", \"u1\", hexUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", hexTarget );\n\t\taddLine( \"p\", \"c\", hexCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", hexCross );\n\t\taddLine( \"cn3\", \"cn4\", hexCross );\n\n\t\taddLine( \"cf1\", \"cf2\", hexCross );\n\t\taddLine( \"cf3\", \"cf4\", hexCross );\n\n\t\tfunction addLine( a, b, hex ) {\n\n\t\t\taddPoint( a, hex );\n\t\t\taddPoint( b, hex );\n\n\t\t}\n\n\t\tfunction addPoint( id, hex ) {\n\n\t\t\tgeometry.vertices.push( new Vector3() );\n\t\t\tgeometry.colors.push( new Color( hex ) );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( geometry.vertices.length - 1 );\n\n\t\t}\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tgeometry.vertices[ points[ i ] ].copy( vector );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.verticesNeedUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\t// a helper to show the world-axis-aligned bounding box for an object\n\n\tfunction BoundingBoxHelper( object, hex ) {\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0x888888;\n\n\t\tthis.object = object;\n\n\t\tthis.box = new Box3();\n\n\t\tMesh.call( this, new BoxGeometry( 1, 1, 1 ), new MeshBasicMaterial( { color: color, wireframe: true } ) );\n\n\t}\n\n\tBoundingBoxHelper.prototype = Object.create( Mesh.prototype );\n\tBoundingBoxHelper.prototype.constructor = BoundingBoxHelper;\n\n\tBoundingBoxHelper.prototype.update = function () {\n\n\t\tthis.box.setFromObject( this.object );\n\n\t\tthis.box.getSize( this.scale );\n\n\t\tthis.box.getCenter( this.position );\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar 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 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( (object && object.isBox3) ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry = new BufferGeometry();\n\tlineGeometry.addAttribute( 'position', new Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\tvar coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = new Float32Array( [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t] );\n\n\t\tvar colors = new Float32Array( [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t] );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\tvar CatmullRomCurve3 = ( function() {\n\n\t\tvar\n\t\t\ttmp = new Vector3(),\n\t\t\tpx = new CubicPoly(),\n\t\t\tpy = new CubicPoly(),\n\t\t\tpz = new CubicPoly();\n\n\t\t/*\n\t\tBased on an optimized c++ solution in\n\t\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t\t - http://ideone.com/NoEbVM\n\n\t\tThis CubicPoly class could be used for reusing some variables and calculations,\n\t\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\t\twhich can be placed in CurveUtils.\n\t\t*/\n\n\t\tfunction CubicPoly() {}\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tCubicPoly.prototype.init = function( x0, x1, t0, t1 ) {\n\n\t\t\tthis.c0 = x0;\n\t\t\tthis.c1 = t0;\n\t\t\tthis.c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tthis.c3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t};\n\n\t\tCubicPoly.prototype.initNonuniformCatmullRom = function( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\t// initCubicPoly\n\t\t\tthis.init( x1, x2, t1, t2 );\n\n\t\t};\n\n\t\t// standard Catmull-Rom spline: interpolate between x1 and x2 with previous/following points x1/x4\n\t\tCubicPoly.prototype.initCatmullRom = function( x0, x1, x2, x3, tension ) {\n\n\t\t\tthis.init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t};\n\n\t\tCubicPoly.prototype.calc = function( t ) {\n\n\t\t\tvar t2 = t * t;\n\t\t\tvar t3 = t2 * t;\n\t\t\treturn this.c0 + this.c1 * t + this.c2 * t2 + this.c3 * t3;\n\n\t\t};\n\n\t\t// Subclass Three.js curve\n\t\treturn Curve.create(\n\n\t\t\tfunction ( p /* array of Vector3 */ ) {\n\n\t\t\t\tthis.points = p || [];\n\t\t\t\tthis.closed = false;\n\n\t\t\t},\n\n\t\t\tfunction ( t ) {\n\n\t\t\t\tvar points = this.points,\n\t\t\t\t\tpoint, intPoint, weight, l;\n\n\t\t\t\tl = points.length;\n\n\t\t\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\t\t\tpoint = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\t\t\tintPoint = Math.floor( point );\n\t\t\t\tweight = point - intPoint;\n\n\t\t\t\tif ( this.closed ) {\n\n\t\t\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\t\t\tintPoint = l - 2;\n\t\t\t\t\tweight = 1;\n\n\t\t\t\t}\n\n\t\t\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\t\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate first point\n\t\t\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\t\t\tp0 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tp1 = points[ intPoint % l ];\n\t\t\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\t\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// extrapolate last point\n\t\t\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\t\t\tp3 = tmp;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t\t\t// safety check for repeated points\n\t\t\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t\t\t}\n\n\t\t\t\tvar v = new Vector3(\n\t\t\t\t\tpx.calc( weight ),\n\t\t\t\t\tpy.calc( weight ),\n\t\t\t\t\tpz.calc( weight )\n\t\t\t\t);\n\n\t\t\t\treturn v;\n\n\t\t\t}\n\n\t\t);\n\n\t} )();\n\n\t/**************************************************************\n\t *\tClosed Spline 3D curve\n\t **************************************************************/\n\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t/**************************************************************\n\t *\tSpline 3D curve\n\t **************************************************************/\n\n\n\tvar SplineCurve3 = Curve.create(\n\n\t\tfunction ( points /* array of Vector3 */ ) {\n\n\t\t\tconsole.warn( 'THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3' );\n\t\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar points = this.points;\n\t\t\tvar point = ( points.length - 1 ) * t;\n\n\t\t\tvar intPoint = Math.floor( point );\n\t\t\tvar weight = point - intPoint;\n\n\t\t\tvar point0 = points[ intPoint == 0 ? intPoint : intPoint - 1 ];\n\t\t\tvar point1 = points[ intPoint ];\n\t\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\t\tvar interpolate = CurveUtils.interpolate;\n\n\t\t\treturn new Vector3(\n\t\t\t\tinterpolate( point0.x, point1.x, point2.x, point3.x, weight ),\n\t\t\t\tinterpolate( point0.y, point1.y, point2.y, point3.y, weight ),\n\t\t\t\tinterpolate( point0.z, point1.z, point2.z, point3.z, weight )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tCubic Bezier 3D curve\n\t **************************************************************/\n\n\tvar CubicBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2, v3 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\t\t\tthis.v3 = v3;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b3 = ShapeUtils.b3;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),\n\t\t\t\tb3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),\n\t\t\t\tb3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tQuadratic Bezier 3D curve\n\t **************************************************************/\n\n\tvar QuadraticBezierCurve3 = Curve.create(\n\n\t\tfunction ( v0, v1, v2 ) {\n\n\t\t\tthis.v0 = v0;\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tvar b2 = ShapeUtils.b2;\n\n\t\t\treturn new Vector3(\n\t\t\t\tb2( t, this.v0.x, this.v1.x, this.v2.x ),\n\t\t\t\tb2( t, this.v0.y, this.v1.y, this.v2.y ),\n\t\t\t\tb2( t, this.v0.z, this.v1.z, this.v2.z )\n\t\t\t);\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tLine3D\n\t **************************************************************/\n\n\tvar LineCurve3 = Curve.create(\n\n\t\tfunction ( v1, v2 ) {\n\n\t\t\tthis.v1 = v1;\n\t\t\tthis.v2 = v2;\n\n\t\t},\n\n\t\tfunction ( t ) {\n\n\t\t\tif ( t === 1 ) {\n\n\t\t\t\treturn this.v2.clone();\n\n\t\t\t}\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\t\tvector.multiplyScalar( t );\n\t\t\tvector.add( this.v1 );\n\n\t\t\treturn vector;\n\n\t\t}\n\n\t);\n\n\t/**************************************************************\n\t *\tArc curve\n\t **************************************************************/\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4 ( a, b, c, d, normal, color, materialIndex ) {\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction PointCloud ( geometry, material ) {\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction ParticleSystem ( geometry, material ) {\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\t}\n\n\tfunction PointCloudMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleBasicMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction ParticleSystemMaterial ( parameters ) {\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\t}\n\n\tfunction Vertex ( x, y, z ) {\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\t}\n\n\t//\n\n\tfunction EdgesHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\tfunction WireframeHelper( object, hex ) {\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t},\n\t\tempty: function () {\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Line3.prototype, {\n\t\tcenter: function ( optionalTarget ) {\n\t\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix3.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t}\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\t\textractPosition: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\t\t},\n\t\tsetRotationFromQuaternion: function ( q ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' );\n\t\t\treturn vector.applyProjection( this );\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\t\t},\n\t\trotateAxis: function ( v ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\t\t},\n\t\ttranslate: function ( v ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\t\t},\n\t\trotateX: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\t\t},\n\t\trotateY: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\t\t},\n\t\trotateZ: function ( angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\t\t},\n\t\trotateByAxis: function ( axis, angle ) {\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.assign( Plane.prototype, {\n\t\tisIntersectionLine: function ( line ) {\n\t\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\t\treturn this.intersectsLine( line );\n\t\t}\n\t} );\n\n\tObject.assign( Quaternion.prototype, {\n\t\tmultiplyVector3: function ( vector ) {\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\t\treturn vector.applyQuaternion( this );\n\t\t}\n\t} );\n\n\tObject.assign( Ray.prototype, {\n\t\tisIntersectionBox: function ( box ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\t\t}\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\t\textrude: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\t\t}\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\t\tsetEulerFromRotationMatrix: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Object3D.prototype, {\n\t\tgetChildByName: function ( name ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\t\t},\n\t\trenderDepth: function ( value ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\t\t}\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\t\teulerOrder: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\t\tobjects: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\t\tlength: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Please use .count.' );\n\t\t\t\treturn this.array.length;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\t\taddIndex: function ( index ) {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\t\t\tif ( indexOffset !== undefined ) {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\t\t},\n\t\tclearDrawCalls: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\t\t},\n\t\tcomputeTangents: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\t\t},\n\t\tcomputeOffsets: function () {\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\t\twrapAround: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\t\tmetal: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\t\tderivatives: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tEventDispatcher.prototype = Object.assign( Object.create( {\n\n\t\t// Note: Extra base ensures these properties are not 'assign'ed.\n\n\t\tconstructor: EventDispatcher,\n\n\t\tapply: function ( target ) {\n\n\t\t\tconsole.warn( \"THREE.EventDispatcher: .apply is deprecated, \" +\n\t\t\t\t\t\"just inherit or Object.assign the prototype to mix-in.\" );\n\n\t\t\tObject.assign( target, this );\n\n\t\t}\n\n\t} ), EventDispatcher.prototype );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\t\tdynamic: {\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\t\tsupportsFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\t\t\treturn this.capabilities.vertexTextures;\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\t\t},\n\t\tinitMaterial: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\t\t},\n\t\taddPrePlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\t\t},\n\t\taddPostPlugin: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\t\t},\n\t\tupdateShadowMap: function () {\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.enabled;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.shadowMap.cullFace;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\t\tcullFace: {\n\t\t\tget: function () {\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\t\twrapS: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\t\t\t},\n\t\t\tset: function ( value ) {\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.assign( Audio.prototype, {\n\t\tload: function ( file ) {\n\t\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' );\n\t\t\tvar scope = this;\n\t\t\tvar audioLoader = new AudioLoader();\n\t\t\taudioLoader.load( file, function ( buffer ) {\n\t\t\t\tscope.setBuffer( buffer );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\t} );\n\n\tObject.assign( AudioAnalyser.prototype, {\n\t\tgetData: function ( file ) {\n\t\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\t\treturn this.getFrequencyData();\n\t\t}\n\t} );\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector () {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function ( vector, camera ) {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer () {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.TextureIdCount = TextureIdCount;\n\texports.Texture = Texture;\n\texports.MaterialIdCount = MaterialIdCount;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.XHRLoader = XHRLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.getAudioContext = getAudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3DIdCount = Object3DIdCount;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Spline = Spline;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.ColorKeywords = ColorKeywords;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.ShapePath = ShapePath;\n\texports.Path = Path;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.CurveUtils = CurveUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.BlendingMode = BlendingMode;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.TextureMapping = TextureMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.TextureWrapping = TextureWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.TextureFilter = TextureFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MultiMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Sprite;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n\tObject.defineProperty( exports, 'AudioContext', {\n\t\tget: function () {\n\t\t\treturn exports.getAudioContext();\n\t\t}\n\t});\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 2\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/silver-3da470.bmp\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/silver.bmp\n// module id = 3\n// module chunks = 0","\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\nimport Stats from 'stats-js'\r\nimport DAT from 'dat-gui'\r\n\r\n// when the scene is done initializing, the function passed as `callback` will be executed\r\n// then, every frame, the function passed as `update` will be executed\r\nfunction init(callback, update) {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var framework = {\r\n gui: gui,\r\n stats: stats\r\n };\r\n\r\n // run this function after the window loads\r\n window.addEventListener('load', function() {\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true} );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x020202, 0);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.target.set(0, 0, 0);\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n controls.addEventListener('change', function() {\r\n camera.hasMoved = true;\r\n });\r\n\r\n document.body.appendChild(renderer.domElement);\r\n\r\n // resize the canvas when the window changes\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n }, false);\r\n\r\n // assign THREE.js objects to the object we will return\r\n framework.scene = scene;\r\n framework.camera = camera;\r\n framework.renderer = renderer;\r\n\r\n // begin the animation loop\r\n (function tick() {\r\n stats.begin();\r\n update(framework); // perform any requested updates\r\n renderer.render(scene, camera); // render the scene\r\n stats.end();\r\n requestAnimationFrame(tick); // register to call this again when the browser renders a new frame\r\n })();\r\n\r\n // we will pass the scene, gui, renderer, camera, etc... to the callback function\r\n return callback(framework);\r\n });\r\n}\r\n\r\nexport default {\r\n init: init\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/framework.js","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 5\n// module chunks = 0","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 6\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n height: 1em;\\n border-radius: 1em;\\n background-color: #eee;\\n padding: 0 0.5em;\\n overflow: hidden;\\n}\\n\\n.slider-fg {\\n padding: 1px 0 2px 0;\\n background-color: #aaa;\\n height: 1em;\\n margin-left: -0.5em;\\n padding-right: 0.5em;\\n border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n display: inline-block;\\n border-radius: 1em;\\n background-color: #fff;\\n border: 1px solid #aaa;\\n content: '';\\n float: right;\\n margin-right: -1em;\\n margin-top: -1px;\\n height: 0.9em;\\n width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 7\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 8\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 9\n// module chunks = 0","/////////////////////////////////////\r\n// Marching cubes lookup tables\r\n/////////////////////////////////////\r\n\r\n// Got these tables from https://www.clicktorelease.com/code/bumpy-metaballs/\r\n// These tables are straight from Paul Bourke's page:\r\n// http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/\r\n// who in turn got them from Cory Gene Bloyd.\r\n\r\nvar EDGE_TABLE = new Int32Array([\r\n 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,\r\n 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,\r\n 0x190, 0x99, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,\r\n 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,\r\n 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,\r\n 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,\r\n 0x3a0, 0x2a9, 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac,\r\n 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,\r\n 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f, 0x265, 0x36c,\r\n 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,\r\n 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc,\r\n 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,\r\n 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55, 0x15c,\r\n 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,\r\n 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,\r\n 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,\r\n 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,\r\n 0xcc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,\r\n 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,\r\n 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,\r\n 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,\r\n 0x2fc, 0x3f5, 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,\r\n 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,\r\n 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663, 0x569, 0x460,\r\n 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,\r\n 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0,\r\n 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,\r\n 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33, 0x339, 0x230,\r\n 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,\r\n 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,\r\n 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,\r\n 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0\r\n])\r\n\r\nvar TRI_TABLE = new Int32Array([\r\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,\r\n 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,\r\n 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1,\r\n 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1,\r\n 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1,\r\n 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1,\r\n 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1,\r\n 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1,\r\n 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1,\r\n 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1,\r\n 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1,\r\n 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1,\r\n 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,\r\n 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,\r\n 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,\r\n 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,\r\n 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,\r\n 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,\r\n 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,\r\n 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,\r\n 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,\r\n 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,\r\n 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,\r\n 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,\r\n 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,\r\n 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,\r\n 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,\r\n 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,\r\n 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,\r\n 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,\r\n 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,\r\n 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,\r\n 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,\r\n 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,\r\n 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,\r\n 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,\r\n 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,\r\n 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,\r\n 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,\r\n 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,\r\n 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1,\r\n 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1,\r\n 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1,\r\n 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1,\r\n 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1,\r\n 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1,\r\n 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1,\r\n 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1,\r\n 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1,\r\n 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1,\r\n 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1,\r\n 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1,\r\n 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1,\r\n 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1,\r\n 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1,\r\n 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1,\r\n 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1,\r\n 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1,\r\n 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1,\r\n 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1,\r\n 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1,\r\n 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1,\r\n 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1,\r\n 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1,\r\n 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1,\r\n 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1,\r\n 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1,\r\n 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1,\r\n 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1,\r\n 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1,\r\n 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1,\r\n 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1,\r\n 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1,\r\n 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1,\r\n 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1,\r\n 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1,\r\n 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1,\r\n 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1,\r\n 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1,\r\n 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1,\r\n 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1,\r\n 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1,\r\n 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1,\r\n 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1,\r\n 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1,\r\n 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1,\r\n 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1,\r\n 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1,\r\n 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1,\r\n 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1,\r\n 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1,\r\n 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1,\r\n 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1,\r\n 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1,\r\n 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1,\r\n 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1,\r\n 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1,\r\n 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1,\r\n 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1,\r\n 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1,\r\n 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1,\r\n 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1,\r\n 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\r\n 0, 3, 8, -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, -1, -1\r\n]);\r\n\r\nexport default {\r\n EDGE_TABLE: EDGE_TABLE,\r\n TRI_TABLE: TRI_TABLE\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cube_LUT.js","const THREE = require('three');\r\nimport {silverTexture} from './textures'\r\n\r\nimport Metaball from './metaball.js';\r\nimport InspectPoint from './inspect_point.js'\r\nimport LUT from './marching_cube_LUT.js';\r\nvar VISUAL_DEBUG = true;\r\nvar episolon = 0.1;\r\nvar balls = [];\r\n\r\nvar options = {lightColor: '#ffffff',lightIntensity: 1,ambient: '#111111',texture: null};\r\n\r\n// lava\r\nvar l_mat = {\r\n uniforms: {\r\n texture: {type: \"t\",value: null},\r\n u_ambient: {type: 'v3',value: new THREE.Color(options.ambient)},\r\n u_lightCol: {type: 'v3',value: new THREE.Color(options.lightColor)},\r\n u_lightIntensity: {type: 'f',value: options.lightIntensity}\r\n },\r\n vertexShader: require('./shaders/lava-vert.glsl'),\r\n fragmentShader: require('./shaders/lava-frag.glsl')\r\n};\r\n\r\nconst LAVA_MAT = new THREE.ShaderMaterial(l_mat);\r\nconst LAMBERT_WHITE = new THREE.MeshLambertMaterial({ color: 0x111111, emissive: 0xff0000 });\r\nconst LAMBERT_GREEN = new THREE.MeshBasicMaterial( { color: 0x00ee00, transparent: true, opacity: 0.5 });\r\nconst WIREFRAME_MAT = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 10 } );\r\n\r\n// This function samples a point from the metaball's density function\r\n// Implement a function that returns the value of the all metaballs influence to a given point.\r\n// Please follow the resources given in the write-up for details.\r\nfunction sample(point) {\r\n var isovalue = 0.0;\r\n for (var i = 0; i < balls.length; i ++) {\r\n var r = balls[i].radius;\r\n var d = point.distanceTo(balls[i].pos);\r\n //isovalue += (r * r / (d * d)) * balls[i].neg;\r\n isovalue += (r * r / (d * d));\r\n }\r\n return isovalue;\r\n}\r\n\r\nexport default class MarchingCubes {\r\n\r\n constructor(App) {\r\n this.init(App);\r\n }\r\n\r\n init(App) {\r\n this.isPaused = false;\r\n VISUAL_DEBUG = App.config.visualDebug;\r\n\r\n // Initializing member variables.\r\n // Additional variables are used for fast computation.\r\n this.origin = new THREE.Vector3(0);\r\n\r\n this.isolevel = App.config.isolevel;\r\n this.minRadius = App.config.minRadius;\r\n this.maxRadius = App.config.maxRadius;\r\n\r\n this.gridCellWidth = App.config.gridCellWidth;\r\n this.gridCellHeight = App.config.gridCellHeight;\r\n this.gridCellDepth = App.config.gridCellDepth;\r\n this.halfCellWidth = App.config.gridCellWidth / 2.0;\r\n this.halfCellHeight = App.config.gridCellHeight / 2.0;\r\n this.halfCellDepth = App.config.gridCellDepth / 2.0;\r\n this.gridWidth = App.config.gridWidth;\r\n this.gridHeight = App.config.gridHeight;\r\n this.gridDepth = App.config.gridDepth;\r\n\r\n this.res = App.config.gridRes;\r\n this.res2 = App.config.gridRes * App.config.gridRes;\r\n this.res3 = App.config.gridRes * App.config.gridRes * App.config.gridRes;\r\n\r\n this.maxSpeedX = App.config.maxSpeedX;\r\n this.maxSpeedY = App.config.maxSpeedY;\r\n this.maxSpeedZ = App.config.maxSpeedZ;\r\n this.numMetaballs = App.config.numMetaballs;\r\n\r\n this.camera = App.camera;\r\n this.scene = App.scene;\r\n\r\n this.voxels = [];\r\n //this.labels = [];\r\n this.balls = balls;\r\n\r\n this.showSpheres = true;\r\n this.showGrid = true;\r\n\r\n silverTexture.then(function(texture) {\r\n l_mat.uniforms.texture.value = texture;\r\n });\r\n\r\n if (App.config.material) {\r\n this.material = new THREE.MeshPhongMaterial({ color: 0xff6a1d});\r\n } else {\r\n this.material = App.config.material;\r\n }\r\n\r\n this.setupCells();\r\n this.setupMetaballs();\r\n this.makeMesh();\r\n };\r\n\r\n reset() {\r\n \tthis.scene.remove(this.mesh);\r\n \tthis.balls = []; balls = [];\r\n };\r\n\r\n // Convert from 1D index to 3D indices\r\n i1toi3(i1) {\r\n\r\n // [i % w, i % (h * w)) / w, i / (h * w)]\r\n\r\n // @note: ~~ is a fast substitute for Math.floor()\r\n return [\r\n i1 % this.res,\r\n ~~ ((i1 % this.res2) / this.res),\r\n ~~ (i1 / this.res2)\r\n ];\r\n };\r\n\r\n // Convert from 3D indices to 1 1D\r\n i3toi1(i3x, i3y, i3z) {\r\n\r\n // [x + y * w + z * w * h]\r\n\r\n return i3x + i3y * this.res + i3z * this.res2;\r\n };\r\n\r\n // Convert from 3D indices to 3D positions\r\n i3toPos(i3) {\r\n\r\n return new THREE.Vector3(\r\n i3[0] * this.gridCellWidth + this.origin.x + this.halfCellWidth,\r\n i3[1] * this.gridCellHeight + this.origin.y + this.halfCellHeight,\r\n i3[2] * this.gridCellDepth + this.origin.z + this.halfCellDepth\r\n );\r\n };\r\n\r\n setupCells() {\r\n\r\n // Allocate voxels based on our grid resolution\r\n this.voxels = [];\r\n for (var i = 0; i < this.res3; i++) {\r\n var i3 = this.i1toi3(i);\r\n var {x, y, z} = this.i3toPos(i3);\r\n var voxel = new Voxel(new THREE.Vector3(x, y, z), this.gridCellWidth, this.gridCellHeight, this.gridCellDepth);\r\n this.voxels.push(voxel);\r\n\r\n if (VISUAL_DEBUG) {\r\n this.scene.add(voxel.wireframe);\r\n this.scene.add(voxel.mesh);\r\n }\r\n }\r\n }\r\n\r\n setupMetaballs() {\r\n\r\n var x, y, z, vx, vy, vz, radius, pos, vel;\r\n var matLambertWhite = LAMBERT_WHITE;\r\n var maxRadiusTRippled = this.maxRadius * 3;\r\n var maxRadiusDoubled = this.maxRadius * 2;\r\n\r\n // Randomly generate metaballs with different sizes and velocities\r\n for (var i = 0; i < this.numMetaballs; i++) {\r\n x = this.gridWidth / 2;\r\n y = this.gridHeight / 2;\r\n z = this.gridDepth / 2;\r\n pos = new THREE.Vector3(3, 3, 3);\r\n\r\n vx = 0\r\n vy = (Math.random() * 2 - 1) * this.maxSpeedY/10;\r\n vz = 0\r\n vel = new THREE.Vector3(vx, vy, vz);\r\n\r\n radius = Math.random() * (this.maxRadius - this.minRadius) + this.minRadius;\r\n var neg = 1;\r\n if (Math.random()>0.75) neg = -1;\r\n var ball = new Metaball(pos, radius, vel, neg, this.gridWidth, this.gridHeight, this.gridDepth, VISUAL_DEBUG);\r\n balls.push(ball);\r\n\r\n // if (VISUAL_DEBUG) {\r\n // this.scene.add(ball.mesh);\r\n // }\r\n }\r\n this.balls = balls;\r\n }\r\n\r\n update() {\r\n\r\n if (this.isPaused) {\r\n return;\r\n }\r\n\r\n // This should move the metaballs\r\n balls.forEach(function(ball) {\r\n ball.update();\r\n });\r\n this.balls = balls;\r\n\r\n for (var c = 0; c < this.res3; c++) { // every voxel\r\n\r\n // Sampling the center and vertex points\r\n this.voxels[c].center.isovalue = sample(this.voxels[c].center.pos);\r\n for (var i = 0; i < 8; i ++) {\r\n this.voxels[c].corners[i].isovalue = sample(this.voxels[c].corners[i].pos);\r\n }\r\n\r\n // Visualizing grid\r\n if (VISUAL_DEBUG && this.showGrid) {\r\n\r\n // Toggle voxels on or off\r\n if (this.voxels[c].center.isovalue > this.isolevel) {\r\n this.voxels[c].show();\r\n } else {\r\n this.voxels[c].hide();\r\n }\r\n this.voxels[c].center.updateLabel(this.camera);\r\n } else {\r\n this.voxels[c].center.clearLabel();\r\n }\r\n }\r\n\r\n this.updateMesh();\r\n }\r\n\r\n pause() {\r\n this.isPaused = true;\r\n }\r\n\r\n play() {\r\n this.isPaused = false;\r\n }\r\n\r\n show() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].show();\r\n }\r\n this.showGrid = true;\r\n };\r\n\r\n hide() {\r\n for (var i = 0; i < this.res3; i++) {\r\n this.voxels[i].hide();\r\n }\r\n this.showGrid = false;\r\n };\r\n\r\n makeMesh() {\r\n // @TODO\r\n var geo = new THREE.Geometry();\r\n this.mesh = new THREE.Mesh(geo, LAVA_MAT);\r\n this.mesh.geometry.dynamic = true;\r\n this.scene.add(this.mesh);\r\n }\r\n\r\n updateMesh() {\r\n // @TODO\r\n var vertices = [];\r\n var faces = [];\r\n var count = 0;\r\n for (var i = 0; i < this.res3; i ++) {\r\n var vox_count = 0;\r\n var vANDn = this.voxels[i].polygonize(this.isolevel);\r\n for (var j = 0; j < vANDn.vertPositions.length/3; j ++) {\r\n var normals = [];\r\n for (var k = 0; k < 3; k ++) {\r\n vertices.push(vANDn.vertPositions[vox_count]);\r\n normals.push(vANDn.vertNormals[vox_count]);\r\n vox_count++;\r\n count++;\r\n }\r\n faces.push(new THREE.Face3(count - 3, count - 2, count - 1, normals));\r\n }\r\n }\r\n this.mesh.geometry.vertices = vertices;\r\n //this.mesh.geometry.normals = normals;\r\n this.mesh.geometry.faces = faces;\r\n this.mesh.geometry.verticesNeedUpdate = true;\r\n this.mesh.geometry.normalsNeedUpdate = true;\r\n this.mesh.geometry.elementsNeedUpdate = true;\r\n this.mesh.geometry.computeFaceNormals();\r\n //console.log(this.mesh);\r\n }\r\n};\r\n\r\n// ------------------------------------------- //\r\n\r\nclass Voxel {\r\n\r\n constructor(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.init(position, gridCellWidth, gridCellHeight, gridCellDepth);\r\n }\r\n\r\n init(position, gridCellWidth, gridCellHeight, gridCellDepth) {\r\n this.pos = position;\r\n this.gridCellWidth = gridCellWidth;\r\n this.gridCellHeight = gridCellHeight;\r\n this.gridCellDepth = gridCellDepth;\r\n this.corners = [];\r\n\r\n if (VISUAL_DEBUG) {\r\n this.makeMesh();\r\n }\r\n\r\n this.makeInspectPoints();\r\n }\r\n\r\n makeMesh() {\r\n var halfGridCellWidth = this.gridCellWidth / 2.0;\r\n var halfGridCellHeight = this.gridCellHeight / 2.0;\r\n var halfGridCellDepth = this.gridCellDepth / 2.0;\r\n\r\n var positions = new Float32Array([\r\n // Front face\r\n halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, halfGridCellDepth,\r\n -halfGridCellWidth, halfGridCellHeight, halfGridCellDepth,\r\n\r\n // Back face\r\n -halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n -halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, -halfGridCellHeight, -halfGridCellDepth,\r\n halfGridCellWidth, halfGridCellHeight, -halfGridCellDepth,\r\n ]);\r\n\r\n var indices = new Uint16Array([\r\n 0, 1, 2, 3,\r\n 4, 5, 6, 7,\r\n 0, 7, 7, 4,\r\n 4, 3, 3, 0,\r\n 1, 6, 6, 5,\r\n 5, 2, 2, 1\r\n ]);\r\n\r\n // Buffer geometry\r\n var geo = new THREE.BufferGeometry();\r\n geo.setIndex( new THREE.BufferAttribute( indices, 1 ) );\r\n geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\r\n\r\n // Wireframe line segments\r\n this.wireframe = new THREE.LineSegments( geo, WIREFRAME_MAT );\r\n this.wireframe.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n\r\n // Green cube\r\n geo = new THREE.BoxBufferGeometry(this.gridCellWidth, this.gridCellWidth, this.gridCellWidth);\r\n this.mesh = new THREE.Mesh( geo, LAMBERT_GREEN );\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n\r\n makeInspectPoints() {\r\n var w = this.gridCellWidth / 2.0;\r\n var h = this.gridCellHeight / 2.0;\r\n var d = this.gridCellDepth / 2.0;\r\n var x = this.pos.x;\r\n var y = this.pos.y;\r\n var z = this.pos.z;\r\n var red = 0xff0000;\r\n\r\n // Center dot\r\n this.center = new InspectPoint(new THREE.Vector3(x, y, z), 0, VISUAL_DEBUG);\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y-h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z-d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x+w, y+h, z+d), 0, VISUAL_DEBUG));\r\n this.corners.push(new InspectPoint(new THREE.Vector3(x-w, y+h, z+d), 0, VISUAL_DEBUG));\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n if (this.wireframe) {\r\n this.wireframe.visible = true;\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n\r\n if (this.wireframe) {\r\n this.wireframe.visible = false;\r\n }\r\n\r\n if (this.center) {\r\n this.center.clearLabel();\r\n }\r\n }\r\n\r\n vertexLerp(isolevel, posA, posB) {\r\n var t = (isolevel - posA.isovalue) / (posB.isovalue - posA.isovalue);\r\n var lerpPos = new THREE.Vector3();\r\n return lerpPos.lerpVectors(posA.pos, posB.pos, t);\r\n }\r\n\r\n // returns an array of points on the cube edges\r\n // null if no point exists for an edge\r\n edgePoints(edges, x) {\r\n var points = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n if (edges & 1) points[0] = this.vertexLerp(x, this.corners[0], this.corners[1]);\r\n if (edges & 2) points[1] = this.vertexLerp(x, this.corners[1], this.corners[2]);\r\n if (edges & 4) points[2] = this.vertexLerp(x, this.corners[2], this.corners[3]);\r\n if (edges & 8) points[3] = this.vertexLerp(x, this.corners[3], this.corners[0]);\r\n if (edges & 16) points[4] = this.vertexLerp(x, this.corners[4], this.corners[5]);\r\n if (edges & 32) points[5] = this.vertexLerp(x, this.corners[5], this.corners[6]);\r\n if (edges & 64) points[6] = this.vertexLerp(x, this.corners[6], this.corners[7]);\r\n if (edges & 128) points[7] = this.vertexLerp(x, this.corners[7], this.corners[4]);\r\n if (edges & 256) points[8] = this.vertexLerp(x, this.corners[4], this.corners[0]);\r\n if (edges & 512) points[9] = this.vertexLerp(x, this.corners[5], this.corners[1]);\r\n if (edges & 1024) points[10] = this.vertexLerp(x, this.corners[6], this.corners[2]);\r\n if (edges & 2048) points[11] = this.vertexLerp(x, this.corners[7], this.corners[3]);\r\n return points;\r\n }\r\n\r\n getNormal(point) {\r\n var x0 = new THREE.Vector3(point.x - episolon, point.y, point.z);\r\n var x1 = new THREE.Vector3(point.x + episolon, point.y, point.z);\r\n var x = sample(x1) - sample(x0);\r\n var y0 = new THREE.Vector3(point.x, point.y - episolon, point.z);\r\n var y1 = new THREE.Vector3(point.x, point.y + episolon, point.z);\r\n var y = sample(y1) - sample(y0);\r\n var z0 = new THREE.Vector3(point.x, point.y, point.z - episolon);\r\n var z1 = new THREE.Vector3(point.x, point.y, point.z + episolon);\r\n var z = sample(z1) - sample(z0);\r\n var n = new THREE.Vector3(x,y,z);\r\n return n.normalize();\r\n }\r\n\r\n polygonize(isolevel) {\r\n\r\n var vertexList = [];\r\n var normalList = [];\r\n var faceList = [];\r\n\r\n // get corner vertices that are inside metaballs\r\n var corner = 1;\r\n var allVert = 0;\r\n for (var i = 0; i < 8; i ++) {\r\n if (this.corners[i].isovalue > isolevel) {\r\n allVert |= corner;\r\n }\r\n corner = corner << 1;\r\n }\r\n\r\n if (allVert != 0) {\r\n // get intersected edges\r\n var edges = LUT.EDGE_TABLE[allVert];\r\n\r\n // get 12 points\r\n var points = this.edgePoints(edges, isolevel);\r\n\r\n for (var j = 0; j < 16; j ++) {\r\n var tri = LUT.TRI_TABLE[allVert*16 + j];\r\n if (tri < 0) break;\r\n var vertex = points[tri];\r\n vertexList.push(vertex);\r\n normalList.push(this.getNormal(vertex));\r\n }\r\n }\r\n\r\n\r\n return {\r\n vertPositions: vertexList,\r\n vertNormals: normalList\r\n };\r\n };\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/marching_cubes.js","const THREE = require('three')\r\n\r\nvar SPHERE_GEO = new THREE.SphereBufferGeometry(1, 32, 32);\r\nvar LAMBERT_WHITE = new THREE.MeshLambertMaterial( { color: 0x9EB3D8, transparent: true, opacity: 0.5 });\r\n\r\nexport default class Metaball {\r\n constructor(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.init(pos, radius, vel, gridWidth, gridHeight, gridDepth, visualDebug);\r\n }\r\n\r\n init(pos, radius, vel, neg, gridWidth, gridHeight, gridDepth, visualDebug) {\r\n this.gridWidth = gridWidth;\r\n this.gridHeight = gridHeight;\r\n this.gridDepth = gridDepth;\r\n this.pos = pos;\r\n this.vel = vel;\r\n this.neg = neg;\r\n this.radius = radius;\r\n this.radius2 = radius * radius;\r\n this.mesh = null;\r\n this.debug = visualDebug;\r\n // if (visualDebug) {\r\n // this.makeMesh();\r\n // }\r\n }\r\n\r\n makeMesh() {\r\n this.mesh = new THREE.Mesh(SPHERE_GEO, LAMBERT_WHITE);\r\n this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n this.mesh.scale.set(this.radius, this.radius, this.radius);\r\n }\r\n\r\n show() {\r\n if (this.mesh) {\r\n this.mesh.visible = true;\r\n }\r\n };\r\n\r\n hide() {\r\n if (this.mesh) {\r\n this.mesh.visible = false;\r\n }\r\n };\r\n\r\n update() {\r\n\r\n // var cir = new THREE.Vector3(this.pos.x, 0, this.pos.z);\r\n // var disp = new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2).sub(cir);\r\n // var dist = cir.distanceTo(new THREE.Vector3(this.gridWidth/2, 0, this.gridWidth/2));\r\n // if ((dist + 2*this.radius) > this.gridWidth \r\n // || (dist + 2*this.radius) > this.gridDepth) {\r\n // this.vel.add(disp);\r\n // }\r\n var y = (this.pos.y + this.radius) > this.gridHeight || (this.pos.y + 2* this.radius) < 0;\r\n if (y) this.vel.y *= -1;\r\n \r\n var date = new Date();\r\n var velocity = new THREE.Vector3();\r\n velocity.copy(this.vel).multiplyScalar(3);\r\n this.pos.add(velocity);\r\n\r\n \r\n\r\n \r\n // if (x || y || z) {\r\n // this.vel.multiplyScalar(-1);\r\n // }\r\n if (this.debug) this.mesh.position.set(this.pos.x, this.pos.y, this.pos.z);\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/metaball.js","const THREE = require('three');\r\n\r\nconst POINT_MATERIAL = new THREE.PointsMaterial( { color: 0xee1111, size: 10, sizeAttenuation: true } );\r\n\r\nexport default class InspectPoint {\r\n\r\n constructor(pos, isovalue, visualDebug) {\r\n this.init(pos, isovalue, visualDebug);\r\n }\r\n\r\n init(pos, isovalue, visualDebug) {\r\n this.pos = pos;\r\n this.isovalue = isovalue;\r\n this.label = null;\r\n\r\n if (visualDebug) {\r\n this.makeLabel();\r\n }\r\n };\r\n\r\n // Create an HTML div for holding label\r\n makeLabel() {\r\n this.label = document.createElement('div');\r\n this.label.style.position = 'absolute';\r\n this.label.style.width = 100;\r\n this.label.style.height = 100;\r\n this.label.style.userSelect = 'none';\r\n this.label.style.cursor = 'default';\r\n this.label.style.fontSize = '0.3em';\r\n this.label.style.pointerEvents = 'none';\r\n document.body.appendChild(this.label); \r\n };\r\n\r\n updateLabel(camera) {\r\n if (this.label) {\r\n var screenPos = this.pos.clone().project(camera);\r\n screenPos.x = ( screenPos.x + 1 ) / 2 * window.innerWidth;;\r\n screenPos.y = - ( screenPos.y - 1 ) / 2 * window.innerHeight;;\r\n\r\n this.label.style.top = screenPos.y + 'px';\r\n this.label.style.left = screenPos.x + 'px';\r\n this.label.innerHTML = this.isovalue.toFixed(2);\r\n this.label.style.opacity = this.isovalue - 0.5; \r\n }\r\n };\r\n\r\n clearLabel() {\r\n if (this.label) {\r\n this.label.innerHTML = '';\r\n this.label.style.opacity = 0;\r\n }\r\n };\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/inspect_point.js","module.exports = \"\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normalMatrix * normal;\\r\\n e_position = normalize(vec3((modelViewMatrix * vec4(position, 1.0)).rgb));\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\nuniform sampler2D texture;\\r\\nuniform vec3 u_ambient;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 ref = reflect(e_position, f_normal);\\r\\n\\tfloat m = 2.0 * sqrt(pow(ref.x, 2.0) + pow(ref.y, 2.0) + pow(ref.z + 1.0, 2.0));\\r\\n float x = f_normal.x/m + 0.5;\\r\\n float y = f_normal.y/m + 0.5;\\r\\n\\r\\n vec4 color = texture2D(texture, vec2(x,y));\\r\\n\\r\\n gl_FragColor = vec4(color.rgb * u_lightCol * u_lightIntensity + u_ambient, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/lava-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","'use strict';\n\nmodule.exports = function (THREE) {\n\n /**\n * @author mrdoob / http://mrdoob.com/\n */\n THREE.OBJLoader = function (manager) {\n\n this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;\n };\n\n THREE.OBJLoader.prototype = {\n\n constructor: THREE.OBJLoader,\n\n load: function load(url, onLoad, onProgress, onError) {\n\n var scope = this;\n\n var loader = new THREE.XHRLoader(scope.manager);\n loader.load(url, function (text) {\n\n onLoad(scope.parse(text));\n }, onProgress, onError);\n },\n\n parse: function parse(text) {\n\n console.time('OBJLoader');\n\n var object,\n objects = [];\n var geometry, material;\n\n function parseVertexIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + vertices.length / 3) * 3;\n }\n\n function parseNormalIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + normals.length / 3) * 3;\n }\n\n function parseUVIndex(value) {\n\n var index = parseInt(value);\n\n return (index >= 0 ? index - 1 : index + uvs.length / 2) * 2;\n }\n\n function addVertex(a, b, c) {\n\n geometry.vertices.push(vertices[a], vertices[a + 1], vertices[a + 2], vertices[b], vertices[b + 1], vertices[b + 2], vertices[c], vertices[c + 1], vertices[c + 2]);\n }\n\n function addNormal(a, b, c) {\n\n geometry.normals.push(normals[a], normals[a + 1], normals[a + 2], normals[b], normals[b + 1], normals[b + 2], normals[c], normals[c + 1], normals[c + 2]);\n }\n\n function addUV(a, b, c) {\n\n geometry.uvs.push(uvs[a], uvs[a + 1], uvs[b], uvs[b + 1], uvs[c], uvs[c + 1]);\n }\n\n function addFace(a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n\n var ia = parseVertexIndex(a);\n var ib = parseVertexIndex(b);\n var ic = parseVertexIndex(c);\n var id;\n\n if (d === undefined) {\n\n addVertex(ia, ib, ic);\n } else {\n\n id = parseVertexIndex(d);\n\n addVertex(ia, ib, id);\n addVertex(ib, ic, id);\n }\n\n if (ua !== undefined) {\n\n ia = parseUVIndex(ua);\n ib = parseUVIndex(ub);\n ic = parseUVIndex(uc);\n\n if (d === undefined) {\n\n addUV(ia, ib, ic);\n } else {\n\n id = parseUVIndex(ud);\n\n addUV(ia, ib, id);\n addUV(ib, ic, id);\n }\n }\n\n if (na !== undefined) {\n\n ia = parseNormalIndex(na);\n ib = parseNormalIndex(nb);\n ic = parseNormalIndex(nc);\n\n if (d === undefined) {\n\n addNormal(ia, ib, ic);\n } else {\n\n id = parseNormalIndex(nd);\n\n addNormal(ia, ib, id);\n addNormal(ib, ic, id);\n }\n }\n }\n\n // create mesh if no objects in text\n\n if (/^o /gm.test(text) === false) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: '',\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n }\n\n var vertices = [];\n var normals = [];\n var uvs = [];\n\n // v float float float\n\n var vertex_pattern = /v( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vn float float float\n\n var normal_pattern = /vn( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // vt float float\n\n var uv_pattern = /vt( +[\\d|\\.|\\+|\\-|e|E]+)( +[\\d|\\.|\\+|\\-|e|E]+)/;\n\n // f vertex vertex vertex ...\n\n var face_pattern1 = /f( +-?\\d+)( +-?\\d+)( +-?\\d+)( +-?\\d+)?/;\n\n // f vertex/uv vertex/uv vertex/uv ...\n\n var face_pattern2 = /f( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...\n\n var face_pattern3 = /f( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))( +(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/;\n\n // f vertex//normal vertex//normal vertex//normal ...\n\n var face_pattern4 = /f( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))( +(-?\\d+)\\/\\/(-?\\d+))?/;\n\n //\n\n var lines = text.split('\\n');\n\n for (var i = 0; i < lines.length; i++) {\n\n var line = lines[i];\n line = line.trim();\n\n var result;\n\n if (line.length === 0 || line.charAt(0) === '#') {\n\n continue;\n } else if ((result = vertex_pattern.exec(line)) !== null) {\n\n // [\"v 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n vertices.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = normal_pattern.exec(line)) !== null) {\n\n // [\"vn 1.0 2.0 3.0\", \"1.0\", \"2.0\", \"3.0\"]\n\n normals.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n } else if ((result = uv_pattern.exec(line)) !== null) {\n\n // [\"vt 0.1 0.2\", \"0.1\", \"0.2\"]\n\n uvs.push(parseFloat(result[1]), parseFloat(result[2]));\n } else if ((result = face_pattern1.exec(line)) !== null) {\n\n // [\"f 1 2 3\", \"1\", \"2\", \"3\", undefined]\n\n addFace(result[1], result[2], result[3], result[4]);\n } else if ((result = face_pattern2.exec(line)) !== null) {\n\n // [\"f 1/1 2/2 3/3\", \" 1/1\", \"1\", \"1\", \" 2/2\", \"2\", \"2\", \" 3/3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], result[3], result[6], result[9], result[12]);\n } else if ((result = face_pattern3.exec(line)) !== null) {\n\n // [\"f 1/1/1 2/2/2 3/3/3\", \" 1/1/1\", \"1\", \"1\", \"1\", \" 2/2/2\", \"2\", \"2\", \"2\", \" 3/3/3\", \"3\", \"3\", \"3\", undefined, undefined, undefined, undefined]\n\n addFace(result[2], result[6], result[10], result[14], result[3], result[7], result[11], result[15], result[4], result[8], result[12], result[16]);\n } else if ((result = face_pattern4.exec(line)) !== null) {\n\n // [\"f 1//1 2//2 3//3\", \" 1//1\", \"1\", \"1\", \" 2//2\", \"2\", \"2\", \" 3//3\", \"3\", \"3\", undefined, undefined, undefined]\n\n addFace(result[2], result[5], result[8], result[11], undefined, undefined, undefined, undefined, result[3], result[6], result[9], result[12]);\n } else if (/^o /.test(line)) {\n\n geometry = {\n vertices: [],\n normals: [],\n uvs: []\n };\n\n material = {\n name: ''\n };\n\n object = {\n name: line.substring(2).trim(),\n geometry: geometry,\n material: material\n };\n\n objects.push(object);\n } else if (/^g /.test(line)) {\n\n // group\n\n } else if (/^usemtl /.test(line)) {\n\n // material\n\n material.name = line.substring(7).trim();\n } else if (/^mtllib /.test(line)) {\n\n // mtl file\n\n } else if (/^s /.test(line)) {\n\n // smooth shading\n\n } else {\n\n // console.log( \"THREE.OBJLoader: Unhandled line \" + line );\n\n }\n }\n\n var container = new THREE.Object3D();\n var l;\n\n for (i = 0, l = objects.length; i < l; i++) {\n\n object = objects[i];\n geometry = object.geometry;\n\n var buffergeometry = new THREE.BufferGeometry();\n\n buffergeometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(geometry.vertices), 3));\n\n if (geometry.normals.length > 0) {\n\n buffergeometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(geometry.normals), 3));\n }\n\n if (geometry.uvs.length > 0) {\n\n buffergeometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(geometry.uvs), 2));\n }\n\n material = new THREE.MeshLambertMaterial({\n color: 0xff0000\n });\n material.name = object.material.name;\n\n var mesh = new THREE.Mesh(buffergeometry, material);\n mesh.name = object.name;\n\n container.add(mesh);\n }\n\n console.timeEnd('OBJLoader');\n\n return container;\n }\n\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-obj-loader/dist/index.js\n// module id = 17\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 e_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n e_position = cameraPosition;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-vert.glsl\n// module id = 18\n// module chunks = 0","module.exports = \"#define M_PI 3.1415926535897932384626433832795\\r\\n\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\nvarying vec3 e_position;\\r\\n\\r\\nfloat cosine(float a, float b, float c, float d, float t) {\\r\\n\\treturn a + b * cos(2.0 * M_PI * (c * t + d));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tfloat d = clamp(dot(f_normal, normalize(e_position - f_position)), 0.0, 1.0);\\r\\n\\tvec3 rgb = mix(vec3(0.4, 0.3, 0.16), vec3(1.0, 0.3, 0.3), d);\\r\\n\\r\\n gl_FragColor = vec4(d,d,d, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/glass-frag.glsl\n// module id = 19\n// module chunks = 0","module.exports = \"varying vec3 f_normal;\\r\\nvarying vec3 f_position;\\r\\n\\r\\n// uv, position, projectionMatrix, modelViewMatrix, normal\\r\\nvoid main() {\\r\\n f_normal = normal;\\r\\n f_position = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-vert.glsl\n// module id = 20\n// module chunks = 0","module.exports = \"uniform vec3 u_lightPos;\\r\\nuniform vec3 u_lightCol;\\r\\nuniform float u_lightIntensity;\\r\\n\\r\\nvarying vec3 f_position;\\r\\nvarying vec3 f_normal;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\\r\\n float d = clamp(dot(f_normal, normalize(u_lightPos - f_position)), 0.0, 1.0);\\r\\n gl_FragColor = vec4(d * color.rgb * u_lightCol * u_lightIntensity, 1.0);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/shaders/metal-frag.glsl\n// module id = 21\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/glass-5b14a7.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/glass.obj\n// module id = 22\n// module chunks = 0","module.exports = __webpack_public_path__ + \"./assets/lamp-1bcc16.obj\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/lamp.obj\n// module id = 23\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file